aboutsummaryrefslogtreecommitdiff
path: root/include/openvic-dataloader/csv/ValueNode.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/openvic-dataloader/csv/ValueNode.hpp')
-rw-r--r--include/openvic-dataloader/csv/ValueNode.hpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/include/openvic-dataloader/csv/ValueNode.hpp b/include/openvic-dataloader/csv/ValueNode.hpp
new file mode 100644
index 0000000..e66dac0
--- /dev/null
+++ b/include/openvic-dataloader/csv/ValueNode.hpp
@@ -0,0 +1,81 @@
+#pragma once
+
+#include <concepts>
+#include <cstdint>
+#include <initializer_list>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <type_traits>
+#include <variant>
+#include <vector>
+
+#include <fmt/compile.h>
+#include <fmt/core.h>
+#include <fmt/format.h>
+
+namespace ovdl::csv {
+ template<typename T, typename Value>
+ concept IsMap =
+ requires(T t) {
+ { t.begin() } -> std::same_as<typename T::const_iterator>;
+ { t.end() } -> std::same_as<typename T::const_iterator>;
+ { t.empty() } -> std::same_as<bool>;
+ { t.size() } -> std::same_as<typename T::size_type>;
+ { t.at("") } -> std::same_as<const Value&>;
+ { t.find("") } -> std::same_as<typename T::const_iterator>;
+ { t[""] } -> std::same_as<const Value&>;
+ };
+
+ class ValueNode {
+ public:
+ struct Placeholder {
+ static constexpr char ESCAPE_CHAR = '$';
+ static constexpr std::string_view ESCAPE_STR = std::string_view { &ESCAPE_CHAR, 1 };
+
+ std::string value;
+ inline std::string as_string(std::string_view prefix = ESCAPE_STR, std::optional<std::string_view> suffix = std::nullopt) const {
+ return fmt::format(FMT_COMPILE("{}{}{}"), prefix, value, suffix.value_or(prefix));
+ }
+ };
+
+ using internal_value_type = std::variant<std::string, Placeholder>;
+ using position_type = std::uint32_t;
+
+ ValueNode();
+ ValueNode(std::string_view string, position_type position = 0);
+ ValueNode(std::vector<internal_value_type> value_list, position_type position = 0);
+ ValueNode(std::initializer_list<internal_value_type> value_list, position_type position = 0);
+
+ void set_position(position_type position);
+ position_type get_position() const;
+
+ void set_as_list(internal_value_type value);
+ void add_to_list(internal_value_type value);
+ bool list_is_empty() const;
+
+ inline std::string make_from_map(const IsMap<std::string> auto& map) const {
+ std::vector<std::string_view> pre_joined(_value_list.size());
+
+ for (auto&& value : _value_list) {
+ pre_joined.push_back(std::visit([&](auto&& arg) -> std::string_view {
+ using T = std::decay_t<decltype(arg)>;
+ if constexpr (std::is_same_v<T, std::string>) {
+ return arg;
+ } else if constexpr (std::is_same_v<T, Placeholder>) {
+ return map[arg.value];
+ }
+ },
+ value));
+ }
+
+ return fmt::format(FMT_COMPILE("{}"), fmt::join(pre_joined, ""));
+ }
+
+ std::string make(std::string_view prefix = Placeholder::ESCAPE_STR, std::optional<std::string_view> suffix = std::nullopt) const;
+
+ private:
+ position_type _position;
+ std::vector<internal_value_type> _value_list;
+ };
+} \ No newline at end of file