cppfig 0.1.0
Modern C++20 compile-time type-safe configuration library
Loading...
Searching...
No Matches
traits.h
Go to the documentation of this file.
1#pragma once
2
3#include <concepts>
4#include <cstddef>
5#include <cstdint>
6#include <optional>
7#include <string>
8#include <string_view>
9#include <type_traits>
10
11#include "cppfig/value.h"
12
13namespace cppfig {
14
22template <typename T>
27 static auto Serialize(const T& value) -> Value = delete;
28
32 static auto Deserialize(const Value& value) -> std::optional<T> = delete;
33
37 static auto ToString(const T& value) -> std::string = delete;
38
42 static auto FromString(std::string_view str) -> std::optional<T> = delete;
43};
44
49template <typename T>
50concept Configurable = requires(const T& value, const Value& val, std::string_view str) {
51 { ConfigTraits<T>::Serialize(value) } -> std::convertible_to<Value>;
52 { ConfigTraits<T>::Deserialize(val) } -> std::same_as<std::optional<T>>;
53 { ConfigTraits<T>::ToString(value) } -> std::convertible_to<std::string>;
54 { ConfigTraits<T>::FromString(str) } -> std::same_as<std::optional<T>>;
55};
56
57template <>
58struct ConfigTraits<bool> {
59 static auto Serialize(bool value) -> Value { return value; }
60
61 static auto Deserialize(const Value& value) -> std::optional<bool>
62 {
63 if (!value.Fits<bool>()) {
64 return std::nullopt;
65 }
66 return value.Get<bool>();
67 }
68
69 static auto ToString(bool value) -> std::string { return value ? "true" : "false"; }
70
71 static auto FromString(std::string_view str) -> std::optional<bool>
72 {
73 if (str == "true" || str == "1" || str == "yes" || str == "on") {
74 return true;
75 }
76 if (str == "false" || str == "0" || str == "no" || str == "off") {
77 return false;
78 }
79 return std::nullopt;
80 }
81};
82
83template <>
84struct ConfigTraits<int> {
85 static auto Serialize(int value) -> Value { return value; }
86
87 static auto Deserialize(const Value& value) -> std::optional<int>
88 {
89 // Rejects an int64 too large for an int rather than discarding its
90 // high bits, which would turn a plainly wrong value into a
91 // plausible-looking one that then passes validation.
92 if (!value.Fits<int>()) {
93 return std::nullopt;
94 }
95 return value.Get<int>();
96 }
97
98 static auto ToString(int value) -> std::string { return std::to_string(value); }
99
100 static auto FromString(std::string_view str) -> std::optional<int>
101 {
102 try {
103 std::size_t pos = 0;
104 int result = std::stoi(std::string(str), &pos);
105 if (pos != str.size()) {
106 return std::nullopt;
107 }
108 return result;
109 }
110 catch (...) {
111 return std::nullopt;
112 }
113 }
114};
115
116template <>
117struct ConfigTraits<std::int64_t> {
118 static auto Serialize(std::int64_t value) -> Value { return value; }
119
120 static auto Deserialize(const Value& value) -> std::optional<std::int64_t>
121 {
122 if (!value.Fits<std::int64_t>()) {
123 return std::nullopt;
124 }
125 return value.Get<std::int64_t>();
126 }
127
128 static auto ToString(std::int64_t value) -> std::string { return std::to_string(value); }
129
130 static auto FromString(std::string_view str) -> std::optional<std::int64_t>
131 {
132 try {
133 std::size_t pos = 0;
134 std::int64_t result = std::stoll(std::string(str), &pos);
135 if (pos != str.size()) {
136 return std::nullopt;
137 }
138 return result;
139 }
140 catch (...) {
141 return std::nullopt;
142 }
143 }
144};
145
146template <>
147struct ConfigTraits<double> {
148 static auto Serialize(double value) -> Value { return value; }
149
150 static auto Deserialize(const Value& value) -> std::optional<double>
151 {
152 if (!value.Fits<double>()) {
153 return std::nullopt;
154 }
155 return value.Get<double>();
156 }
157
158 static auto ToString(double value) -> std::string { return std::to_string(value); }
159
160 static auto FromString(std::string_view str) -> std::optional<double>
161 {
162 try {
163 std::size_t pos = 0;
164 double result = std::stod(std::string(str), &pos);
165 if (pos != str.size()) {
166 return std::nullopt;
167 }
168 return result;
169 }
170 catch (...) {
171 return std::nullopt;
172 }
173 }
174};
175
176template <>
177struct ConfigTraits<float> {
178 static auto Serialize(float value) -> Value { return value; }
179
180 static auto Deserialize(const Value& value) -> std::optional<float>
181 {
182 // A double outside the float range would otherwise arrive as infinity.
183 if (!value.Fits<float>()) {
184 return std::nullopt;
185 }
186 return value.Get<float>();
187 }
188
189 static auto ToString(float value) -> std::string { return std::to_string(value); }
190
191 static auto FromString(std::string_view str) -> std::optional<float>
192 {
193 try {
194 std::size_t pos = 0;
195 float result = std::stof(std::string(str), &pos);
196 if (pos != str.size()) {
197 return std::nullopt;
198 }
199 return result;
200 }
201 catch (...) {
202 return std::nullopt;
203 }
204 }
205};
206
207template <>
208struct ConfigTraits<std::string> {
209 static auto Serialize(const std::string& value) -> Value { return value; }
210
211 static auto Deserialize(const Value& value) -> std::optional<std::string>
212 {
213 if (!value.Fits<std::string>()) {
214 return std::nullopt;
215 }
216 return value.Get<std::string>();
217 }
218
219 static auto ToString(const std::string& value) -> std::string { return value; }
220
221 static auto FromString(std::string_view str) -> std::optional<std::string> { return std::string(str); }
222};
223
224} // namespace cppfig
A self-contained, recursive value type for configuration data.
Definition value.h:32
Concept constraining types that can be used as configuration values.
Definition traits.h:50
C++20 compile-time type-safe configuration library.
Definition conf.h:17
static auto Serialize(bool value) -> Value
Definition traits.h:59
static auto Deserialize(const Value &value) -> std::optional< bool >
Definition traits.h:61
static auto FromString(std::string_view str) -> std::optional< bool >
Definition traits.h:71
static auto ToString(bool value) -> std::string
Definition traits.h:69
static auto Deserialize(const Value &value) -> std::optional< double >
Definition traits.h:150
static auto ToString(double value) -> std::string
Definition traits.h:158
static auto FromString(std::string_view str) -> std::optional< double >
Definition traits.h:160
static auto Serialize(double value) -> Value
Definition traits.h:148
static auto ToString(float value) -> std::string
Definition traits.h:189
static auto FromString(std::string_view str) -> std::optional< float >
Definition traits.h:191
static auto Deserialize(const Value &value) -> std::optional< float >
Definition traits.h:180
static auto Serialize(float value) -> Value
Definition traits.h:178
static auto Serialize(int value) -> Value
Definition traits.h:85
static auto FromString(std::string_view str) -> std::optional< int >
Definition traits.h:100
static auto Deserialize(const Value &value) -> std::optional< int >
Definition traits.h:87
static auto ToString(int value) -> std::string
Definition traits.h:98
static auto Deserialize(const Value &value) -> std::optional< std::int64_t >
Definition traits.h:120
static auto ToString(std::int64_t value) -> std::string
Definition traits.h:128
static auto FromString(std::string_view str) -> std::optional< std::int64_t >
Definition traits.h:130
static auto Serialize(std::int64_t value) -> Value
Definition traits.h:118
static auto FromString(std::string_view str) -> std::optional< std::string >
Definition traits.h:221
static auto Deserialize(const Value &value) -> std::optional< std::string >
Definition traits.h:211
static auto ToString(const std::string &value) -> std::string
Definition traits.h:219
static auto Serialize(const std::string &value) -> Value
Definition traits.h:209
Primary template for configuration type traits.
Definition traits.h:23
static auto Deserialize(const Value &value) -> std::optional< T >=delete
Deserializes a value from a Value node.
static auto ToString(const T &value) -> std::string=delete
Converts a value to a human-readable string.
static auto FromString(std::string_view str) -> std::optional< T >=delete
Parses a value from a string (e.g., from environment variables).
static auto Serialize(const T &value) -> Value=delete
Serializes a value to a Value node.