ezconfig
Create C++ Objects from Yaml and Json
Loading...
Searching...
No Matches
stl.hpp
1// Copyright (c) 2023 Petter Nilsson. MIT License. https://github.com/pettni/ezconfig
2
3#pragma once
4
5#include <yaml-cpp/yaml.h>
6
7#include "stl_fwd.hpp"
8
9namespace YAML {
10
11template<typename T>
12bool convert<std::optional<T>>::decode(const Node & yaml, std::optional<T> & obj)
13{
14 if (yaml.IsNull()) {
15 obj = std::nullopt;
16 } else {
17 obj = yaml.as<T>();
18 }
19 return true;
20}
21
22template<typename T>
23Node convert<std::optional<T>>::encode(const std::optional<T> & obj)
24{
25 if (obj.has_value()) {
26 return Node(*obj);
27 } else {
28 return Node(Null);
29 }
30}
31
32template<typename K, typename V, typename C, typename A>
33bool convert<std::unordered_map<K, V, C, A>>::decode(const Node & yaml, std::unordered_map<K, V, C, A> & obj)
34{
35 obj.clear();
36 for (const auto & node : yaml) {
37 const auto key = node.first.as<std::string>();
38 if (obj.contains(key)) { throw YAML::ParserException(yaml.Mark(), "Double key '" + key + "' in map"); }
39 obj[node.first.as<K>()] = node.second.as<V>();
40 }
41 return true;
42}
43
44template<typename K, typename V, typename C, typename A>
45Node convert<std::unordered_map<K, V, C, A>>::encode(const std::unordered_map<K, V, C, A> & obj)
46{
47 YAML::Node node;
48 for (const auto & [key, val] : obj) { node[key] = YAML::Node(val); }
49 return node;
50}
51
52inline bool convert<std::filesystem::path>::decode(const Node & yaml, std::filesystem::path & obj)
53{
54 obj = yaml.as<std::string>();
55 return true;
56}
57
58inline Node convert<std::filesystem::path>::encode(const std::filesystem::path & obj) { return Node(obj.string()); }
59
60template<intmax_t Num, intmax_t Den>
61bool convert<std::chrono::duration<int64_t, std::ratio<Num, Den>>>::decode(
62 const Node & yaml, std::chrono::duration<int64_t, std::ratio<Num, Den>> & obj)
63{
64 using RetType = std::chrono::duration<int64_t, std::ratio<Num, Den>>;
65 const auto str = yaml.as<std::string>();
66 if (str.ends_with("ms")) {
67 obj = std::chrono::duration_cast<RetType>(std::chrono::milliseconds(std::stoi(str.substr(0, str.size() - 2))));
68 } else if (str.ends_with("us")) {
69 obj = std::chrono::duration_cast<RetType>(std::chrono::microseconds(std::stoi(str.substr(0, str.size() - 2))));
70 } else if (str.ends_with("ns")) {
71 obj = std::chrono::duration_cast<RetType>(std::chrono::nanoseconds(std::stoi(str.substr(0, str.size() - 2))));
72 } else if (str.ends_with("s")) {
73 obj = std::chrono::duration_cast<RetType>(std::chrono::seconds(std::stoi(str.substr(0, str.size() - 1))));
74 } else if (str.ends_with("m")) {
75 obj = std::chrono::duration_cast<RetType>(std::chrono::minutes(std::stoi(str.substr(0, str.size() - 1))));
76 } else if (str.ends_with("h")) {
77 obj = std::chrono::duration_cast<RetType>(std::chrono::hours(std::stoi(str.substr(0, str.size() - 1))));
78 } else {
79 throw YAML::ParserException{
80 yaml.Mark(),
81 "Could not detect suffix in '" + str + "', expected s, ms, us, or ns",
82 };
83 }
84
85 return true;
86}
87
88template<intmax_t Num, intmax_t Den>
89Node convert<std::chrono::duration<int64_t, std::ratio<Num, Den>>>::encode(
90 const std::chrono::duration<int64_t, std::ratio<Num, Den>> & obj)
91{
92 using R = std::ratio<Num, Den>;
93 if constexpr (std::is_same_v<R, std::milli>) {
94 return std::to_string(obj.count()) + "ms";
95 } else if constexpr (std::is_same_v<R, std::micro>) {
96 return std::to_string(obj.count()) + "us";
97 } else if constexpr (std::is_same_v<R, std::nano>) {
98 return std::to_string(obj.count()) + "ns";
99 } else if constexpr (std::is_same_v<R, std::ratio<1>>) {
100 return std::to_string(obj.count()) + "s";
101 } else if constexpr (std::is_same_v<R, std::ratio<60>>) {
102 return std::to_string(obj.count()) + "m";
103 } else if constexpr (std::is_same_v<R, std::ratio<3600>>) {
104 return std::to_string(obj.count()) + "h";
105 } else {
106 return std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(obj).count()) + "ns";
107 }
108}
109
110} // namespace YAML
YAML forward declarations.
Definition yaml_fwd.hpp:16