diff --git a/src/util/format/builder.cpp b/src/util/format/builder.cpp index a90ee56..8ff3af6 100644 --- a/src/util/format/builder.cpp +++ b/src/util/format/builder.cpp @@ -14,6 +14,7 @@ #include #include "util/format/builder.h" +#include "util/meta/assert.h" namespace Util::Format { @@ -53,4 +54,33 @@ void Builder::putF64(double number, uint8_t precision) const m_builder << string; } +void Builder::putString(std::string_view string, size_t width, Align align, char fill) const +{ + size_t length = string.length(); + if (width < length) { + m_builder.write(string.data(), length); + return; + } + + switch (align) { + case Align::Left: + m_builder.write(string.data(), length); + m_builder << std::string(width - length, fill); + break; + case Align::Center: { + size_t half = (width - length) / 2; + m_builder << std::string(half, fill); + m_builder.write(string.data(), length); + m_builder << std::string(width - half - length, fill); + break; + } + case Align::Right: + m_builder << std::string(width - length, fill); + m_builder.write(string.data(), length); + break; + default: + VERIFY_NOT_REACHED(); + }; +} + } // namespace Util::Format diff --git a/src/util/format/builder.h b/src/util/format/builder.h index f5a8a5f..fd80fbb 100644 --- a/src/util/format/builder.h +++ b/src/util/format/builder.h @@ -43,7 +43,7 @@ public: void putF32(float number, uint8_t precision = 6) const; void putF64(double number, uint8_t precision = 6) const; void putCharacter(char character) const { m_builder.write(&character, 1); } - void putString(const std::string_view string) const { m_builder.write(string.data(), string.length()); } + void putString(std::string_view string, size_t width = 0, Align align = Align::Left, char fill = ' ') const; void putPointer(const void* pointer) const { m_builder << pointer; } const std::stringstream& builder() const { return m_builder; } diff --git a/src/util/format/formatter.cpp b/src/util/format/formatter.cpp index ecc7005..f4abebf 100644 --- a/src/util/format/formatter.cpp +++ b/src/util/format/formatter.cpp @@ -60,10 +60,10 @@ void Formatter::format(Builder& builder, double value) const { if (specifier.precision < 0) { builder.putF64(value); + return; } - else { - builder.putF64(value, specifier.precision); - } + + builder.putF64(value, specifier.precision); } // Char @@ -82,15 +82,22 @@ void Formatter::format(Builder& builder, bool value) const // String -void Formatter::format(Builder& builder, const char* value) const +template<> +void Formatter::format(Builder& builder, std::string_view value) const { - builder.putString(value != nullptr ? std::string_view { value, strlen(value) } : "(nil)"); + if (specifier.align == Builder::Align::None) { + builder.putString(value, specifier.width); + return; + } + + builder.putString(value, specifier.width, specifier.align, specifier.fill); } -template<> -void Formatter::format(Builder& builder, std::string_view value) const +void Formatter::format(Builder& builder, const char* value) const { - builder.putString(value); + Formatter::format( + builder, + value != nullptr ? std::string_view { value, strlen(value) } : "(nil)"); } // Pointer diff --git a/src/util/format/formatter.h b/src/util/format/formatter.h index d906469..64e0088 100644 --- a/src/util/format/formatter.h +++ b/src/util/format/formatter.h @@ -54,7 +54,7 @@ struct Specifier { bool alternativeForm = false; bool zeroPadding = false; - int width = 0; + size_t width = 0; int8_t precision = -1; PresentationType type = PresentationType::None; diff --git a/src/util/format/parser.cpp b/src/util/format/parser.cpp index 5c46148..33b68fb 100644 --- a/src/util/format/parser.cpp +++ b/src/util/format/parser.cpp @@ -274,7 +274,7 @@ void Parser::parseSpecifier(Specifier& specifier, SpecifierType type) // We parse until after the closing '}', so take this into account widthEnd = tell() - 1; } - specifier.width = static_cast(stringToNumber(m_input.substr(widthBegin, widthEnd - widthBegin))); + specifier.width = stringToNumber(m_input.substr(widthBegin, widthEnd - widthBegin)); } if (precisionBegin != std::numeric_limits::max()) {