summaryrefslogtreecommitdiff
path: root/include/fud_format.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/fud_format.hpp')
-rw-r--r--include/fud_format.hpp131
1 files changed, 93 insertions, 38 deletions
diff --git a/include/fud_format.hpp b/include/fud_format.hpp
index ea32bd8..2576eca 100644
--- a/include/fud_format.hpp
+++ b/include/fud_format.hpp
@@ -22,24 +22,30 @@
#include "fud_result.hpp"
#include "fud_status.hpp"
#include "fud_string_view.hpp"
+#include "fud_option.hpp"
#include "fud_utf8.hpp"
#include <cstdint>
-#include <optional>
#include <variant>
+#include <limits>
namespace fud {
struct FormatAlign
{
- enum class Value : uint8_t
+ enum class Value : utf8
{
- Left,
- Right,
- Center
+ Left = '<',
+ Right = '>',
+ Center = '^',
+ Default = std::numeric_limits<utf8>::max()
};
- constexpr static std::optional<FormatAlign> from(utf8 letter)
+ constexpr static FormatAlign makeDefault() noexcept {
+ return {Value::Default};
+ }
+
+ constexpr static Option<FormatAlign> from(utf8 letter)
{
FormatAlign formatAlign;
switch (letter) {
@@ -53,12 +59,16 @@ struct FormatAlign
formatAlign.value = Value::Center;
break;
default:
- return std::nullopt;
+ return NullOpt;
}
return formatAlign;
}
+ Value operator()() const {
+ return value;
+ }
+
Value value;
};
@@ -66,37 +76,50 @@ struct FormatFill {
FormatAlign align;
utf8 fill;
- constexpr static Result<std::optional<FormatFill>, FudStatus> parse(StringView formatView) {
- // "{:A<X}"
- using RetType = Result<std::optional<FormatFill>, FudStatus>;
- if (formatView.length() < 3) {
- return RetType::okay(std::nullopt);
+ constexpr static FormatFill make() noexcept {
+ return FormatFill {FormatAlign::makeDefault(), ' '};
+ }
+
+ constexpr static Result<Option<FormatFill>, FudStatus> make(StringView formatView, size_t& length) noexcept {
+ using RetType = Result<Option<FormatFill>, FudStatus>;
+ if (formatView.length() < 1) {
+ return RetType::okay(NullOpt);
}
const auto* data = formatView.data();
- if (data[0] != 'A') {
- return RetType::okay(std::nullopt);
+ auto align1 = FormatAlign::from(data[0]);
+ decltype(align1) align2 = NullOpt;
+ if (formatView.length() > 1) {
+ align2 = FormatAlign::from(data[1]);
}
- auto align = FormatAlign::from(data[1]);
- if (!align.has_value()) {
- return FudStatus::FormatInvalid;
+ if (align2.hasValue()) {
+ length = 2;
+ auto fill = data[0];
+ if (not Ascii::valid(fill)) {
+ return FudStatus::Utf8Invalid;
+ }
+ if (fill == '{' || fill == '}') {
+ return FudStatus::FormatInvalid;
+ }
+ return RetType::okay(FormatFill{std::move(align2).value(), data[0]});
}
- auto fill = data[2];
- if (!Ascii::valid(fill)) {
- return FudStatus::Utf8Invalid;
+ if (align1.hasValue()) {
+ length = 1;
+ return RetType::okay(FormatFill{std::move(align1).value(), ' '});
}
- return RetType::okay(FormatFill{*align, fill});
+ return RetType::okay(NullOpt);
}
};
enum class FormatSign : uint8_t
{
- Plus,
- Minus,
- Space
+ Plus = '+',
+ Minus = '-',
+ Space = ' ',
+ Default = std::numeric_limits<utf8>::max()
};
enum class FormatStringType : uint8_t
@@ -155,6 +178,7 @@ enum class FormatPointerType : uint8_t
HexUpper
};
+/*
using FormatType = std::variant< // break
std::monostate,
FormatStringType,
@@ -163,33 +187,64 @@ using FormatType = std::variant< // break
FormatBoolType,
FormatFloatingType,
FormatPointerType>;
+*/
+
+enum class FormatType : utf8 {
+ Unspecified = '\0',
+ String = 's',
+ Escaped = '?',
+ BinaryLower = 'b',
+ BinaryUpper = 'B',
+ Character = 'c',
+ Decimal = 'd',
+ Octal = 'o',
+ HexLower = 'x',
+ HexUpper = 'X',
+ FloatHexLower = 'a',
+ FloatHexUpper = 'A',
+ ScientificLower = 'e',
+ ScientificUpper = 'E',
+ FixedLower = 'f',
+ FixedUpper = 'F',
+ GeneralLower = 'g',
+ GeneralUpper = 'G',
+};
struct FormatSpec;
using FormatSpecResult = Result<FormatSpec, FudStatus>;
struct FormatSpec {
- size_t width;
- size_t precision;
- FormatFill fill;
- FormatSign formatSign;
+ static constexpr uint32_t widthUnspecified = std::numeric_limits<uint32_t>::max();
+ static constexpr uint32_t precisionUnspecified = std::numeric_limits<uint32_t>::max();
+ static constexpr uint16_t positionUnspecified = std::numeric_limits<uint16_t>::max();
+ static constexpr utf8 openBracket = '{';
+ static constexpr utf8 closeBracket = '}';
+ static constexpr utf8 formatTypeUnspecified = std::numeric_limits<utf8>::max();
+ static constexpr utf8 localeChar = 'L';
+
+ uint32_t width{widthUnspecified};
+
+ uint32_t precision{precisionUnspecified};
+
+ uint16_t position{positionUnspecified};
+
+ FormatFill fill{FormatFill::make()};
- FormatType formatType;
+ FormatSign formatSign{FormatSign::Default};
- bool hasWidth;
- bool takesWidth;
+ FormatType formatType{};
- bool hasPrecision;
- bool takesPrecision;
+ bool takesWidth{false};
- bool hasFill;
+ bool takesPrecision{false};
- bool hasFormatSign;
+ bool alternateForm{false};
- bool alternateForm;
+ bool leadingZero{false};
- bool leadingZero;
+ bool hasLocale{false};
- static Result<FormatSpec, FudStatus> make(StringView& formatView, size_t specIndex);
+ static Result<FormatSpec, FudStatus> make(StringView formatView, size_t& specLength);
};
} // namespace fud