Iros
 
Loading...
Searching...
No Matches
json_value.h
Go to the documentation of this file.
1#pragma once
2
12#include "di/meta/compare.h"
13#include "di/meta/operations.h"
16#include "di/types/prelude.h"
17#include "di/util/create.h"
19#include "di/util/declval.h"
25
27class Value;
28
29struct Null {
30 explicit Null() = default;
31
32 template<concepts::Encoding Enc>
34 format::FormatParseContext<Enc>& parse_context, bool debug) {
35 return format::formatter<container::StringView>(parse_context, debug) %
36 [](concepts::CopyConstructible auto formatter) {
37 return [=](concepts::FormatContext auto& context, Null) {
38 return formatter(context, "null"_sv);
39 };
40 };
41 }
42
44 return serializer.serialize_null();
45 }
46
47 auto operator==(Null const&) const -> bool = default;
48 auto operator<=>(Null const&) const = default;
49};
50
51constexpr inline auto null = Null {};
52
53using Bool = bool;
54
55// NOTE: this should support floating point in the future.
56using Number = i64;
57
62}
63
64namespace di::concepts::detail {
65template<>
67 constexpr static bool value = true;
68};
69
70template<>
72 constexpr static bool value = true;
73};
74
75template<>
77 constexpr static bool value = true;
78};
79
80template<>
82 constexpr static bool value = true;
83};
84
85template<>
87 using Type = di::strong_ordering;
88};
89
90template<>
92 using Type = di::strong_ordering;
93};
94
95template<>
97 using Type = di::strong_ordering;
98};
99
100template<>
102 using Type = di::strong_ordering;
103};
104}
105
106namespace di::serialization::json {
107class Value : public vocab::Variant<Null, Bool, Number, String, Array, Object> {
109
110 constexpr static usize alternatives = 6;
111
112 template<concepts::SameAs<types::Tag<util::create_in_place>> Tag = types::Tag<util::create_in_place>,
113 typename... Args>
114 requires(concepts::CreatableFrom<String, Args...>)
115 constexpr friend auto tag_invoke(Tag, InPlaceType<Value>, Args&&... args) {
116 return as_fallible(util::create<String>(util::forward<Args>(args)...)) % [](String&& v) {
117 return Value { util::move(v) };
118 } | try_infallible;
119 }
120
121public:
122 using Base::Base;
123 using Base::operator=;
124
125 constexpr auto is_null() const -> bool { return vocab::holds_alternative<Null>(*this); }
126 constexpr auto is_boolean() const -> bool { return vocab::holds_alternative<Bool>(*this); }
127 constexpr auto is_integer() const -> bool { return vocab::holds_alternative<Number>(*this); }
128 constexpr auto is_number() const -> bool { return vocab::holds_alternative<Number>(*this); }
129 constexpr auto is_string() const -> bool { return vocab::holds_alternative<String>(*this); }
130 constexpr auto is_array() const -> bool { return vocab::holds_alternative<Array>(*this); }
131 constexpr auto is_object() const -> bool { return vocab::holds_alternative<Object>(*this); }
132
133 constexpr auto as_boolean() const -> vocab::Optional<Bool> {
134 return vocab::get_if<Bool>(*this) % [](bool v) {
135 return v;
136 };
137 }
138 constexpr auto is_true() const -> bool { return as_boolean() == true; }
139 constexpr auto is_false() const -> bool { return as_boolean() == false; }
140
141 constexpr auto as_integer() const -> vocab::Optional<Number> { return vocab::get_if<Number>(*this); }
142 constexpr auto as_number() const -> vocab::Optional<Number> { return vocab::get_if<Number>(*this); }
143
144 constexpr auto as_string() -> vocab::Optional<String&> { return vocab::get_if<String>(*this); }
145 constexpr auto as_string() const -> vocab::Optional<String const&> { return vocab::get_if<String>(*this); }
146 constexpr auto as_array() -> vocab::Optional<Array&> { return vocab::get_if<Array>(*this); }
147 constexpr auto as_array() const -> vocab::Optional<Array const&> { return vocab::get_if<Array>(*this); }
148 constexpr auto as_object() -> vocab::Optional<Object&> { return vocab::get_if<Object>(*this); }
149 constexpr auto as_object() const -> vocab::Optional<Object const&> { return vocab::get_if<Object>(*this); }
150
151 // Object operator[] overloads.
152 constexpr auto operator[](String const& key) -> decltype(auto) { return force_object()[key]; }
153 constexpr auto operator[](String&& key) -> decltype(auto) { return force_object()[util::move(key)]; }
154
155 template<typename U>
156 requires(requires { util::declval<Object&>()[util::declval<U>()]; })
157 constexpr auto operator[](U&& key) -> decltype(auto) {
158 force_object();
159 return force_object()[util::forward<U>(key)];
160 }
161
162 // Object at overloads.
163 constexpr auto at(String const& key) -> Optional<Value&> {
164 return as_object().and_then([&](auto& o) {
165 return o.at(key);
166 });
167 }
168 constexpr auto at(String const& key) const -> Optional<Value const&> {
169 return as_object().and_then([&](auto const& o) {
170 return o.at(key);
171 });
172 }
173
174 template<typename U>
175 requires(requires { util::declval<Object&>().at(util::declval<U&>()); })
176 constexpr auto at(U&& key) -> Optional<Value&> {
177 return as_object().and_then([&](auto& o) {
178 return o.at(key);
179 });
180 }
181 template<typename U>
182 requires(requires { util::declval<Object const&>().at(util::declval<U&>()); })
183 constexpr auto at(U&& key) const -> Optional<Value const&> {
184 return as_object().and_then([&](auto const& o) {
185 return o.at(key);
186 });
187 }
188
189 // Object contains overloads.
190 constexpr auto contains(String const& key) const -> bool {
191 return as_object()
192 .transform([&](auto const& o) {
193 return o.contains(key);
194 })
195 .value_or(false);
196 }
197 template<typename U>
198 constexpr auto contains(U&& key) const -> bool {
199 return as_object()
200 .transform([&](auto const& o) {
201 return o.contains(util::forward<U>(key));
202 })
203 .value_or(false);
204 }
205
206 // Object erase overloads.
207 constexpr auto erase(String const& key) -> size_t {
208 return as_object()
209 .transform([&](auto& o) {
210 return o.erase(key);
211 })
212 .value_or(0);
213 }
214 template<typename U>
215 requires(requires { util::declval<Object&>().erase(util::declval<U&>()); })
216 constexpr auto erase(U&& key) -> size_t {
217 return as_object()
218 .transform([&](auto& o) {
219 return o.erase(key);
220 })
221 .value_or(0);
222 }
223
224 // Object try_emplace overloads.
225 template<typename... Args>
226 requires(concepts::ConstructibleFrom<Value, Args...>)
227 constexpr auto try_emplace(String const& key, Args&&... args) -> decltype(auto) {
228 return force_object().try_emplace(key, util::forward<Args>(args)...);
229 }
230 template<typename... Args>
231 requires(concepts::ConstructibleFrom<Value, Args...>)
232 constexpr auto try_emplace(String&& key, Args&&... args) -> decltype(auto) {
233 return force_object().try_emplace(util::move(key), util::forward<Args>(args)...);
234 }
235 template<typename U, typename... Args>
236 requires(concepts::ConstructibleFrom<Value, Args...> &&
237 requires { util::declval<Object&>().try_emplace(util::declval<U>(), util::declval<Args>()...); })
238 constexpr auto try_emplace(U&& key, Args&&... args) -> decltype(auto) {
239 return force_object().try_emplace(util::forward<U>(key), util::forward<Args>(args)...);
240 }
241
242 // Object insert_or_assign overloads.
243 template<typename V>
245 constexpr auto insert_or_assign(String const& key, V&& value) -> decltype(auto) {
246 return force_object().insert_or_assign(key, util::forward<V>(value));
247 }
248 template<typename V>
250 constexpr auto insert_or_assign(String&& key, V&& value) -> decltype(auto) {
251 return force_object().insert_or_assign(util::move(key), util::forward<V>(value));
252 }
253 template<typename U, typename V>
255 requires { util::declval<Object&>().insert_or_assign(util::declval<U>(), util::declval<Value>()); })
256 constexpr auto insert_or_assign(U&& key, V&& value) -> decltype(auto) {
257 return force_object().insert_or_assign(util::forward<U>(key), util::forward<V>(value));
258 }
259
260 constexpr auto empty() const -> bool {
262 [](Object const& v) {
263 return v.empty();
264 },
265 [](Array const& v) {
266 return v.empty();
267 },
268 [](auto const&) {
269 return true;
270 }),
271 *this);
272 }
273 constexpr auto size() const -> usize {
275 [](Object const& v) {
276 return v.size();
277 },
278 [](Array const& v) {
279 return v.size();
280 },
281 [](auto const&) {
282 return usize(0);
283 }),
284 *this);
285 }
286
287 constexpr void clear() {
289 [](Object& v) {
290 v.clear();
291 },
292 [](Array& v) {
293 v.clear();
294 },
295 [](auto&) {}),
296 *this);
297 }
298
299 // Array front/back overloads.
300 constexpr auto front() -> Optional<Value&> {
302 [](Array& v) {
303 return v.front();
304 },
305 [](auto&) {
306 return Optional<Value&> {};
307 }),
308 *this);
309 }
310 constexpr auto front() const -> Optional<Value const&> {
312 [](Array const& v) {
313 return v.front();
314 },
315 [](auto const&) {
316 return Optional<Value const&> {};
317 }),
318 *this);
319 }
320
321 constexpr auto back() -> Optional<Value&> {
323 [](Array& v) {
324 return v.back();
325 },
326 [](auto&) {
327 return Optional<Value&> {};
328 }),
329 *this);
330 }
331 constexpr auto back() const -> Optional<Value const&> {
333 [](Array const& v) {
334 return v.back();
335 },
336 [](auto const&) {
337 return Optional<Value const&> {};
338 }),
339 *this);
340 }
341
342 // Array operator[]/at overloads.
343 constexpr auto operator[](usize index) -> Value& { return as_array().value()[index]; }
344 constexpr auto operator[](usize index) const -> Value const& { return as_array().value()[index]; }
345
346 constexpr auto at(usize index) -> Optional<Value&> {
347 return as_array().and_then([&](auto& a) {
348 return a.at(index);
349 });
350 }
351 constexpr auto at(usize index) const -> Optional<Value const&> {
352 return as_array().and_then([&](auto const& a) {
353 return a.at(index);
354 });
355 }
356
357 // Array push_front/pop_back overloads.
358 constexpr auto push_back(Value&& value) -> decltype(auto) { return force_array().push_back(util::move(value)); }
359 constexpr auto pop_back() -> Optional<Value> {
360 return as_array().and_then([](auto& a) {
361 return a.pop_back();
362 });
363 }
364
365private:
366 template<typename S>
367 constexpr friend auto tag_invoke(types::Tag<serialize>, JsonFormat, S& serializer, Value const& value)
369 return vocab::visit(
370 [&](auto const& x) {
371 return serialize(serializer, x);
372 },
373 value);
374 }
375
376 constexpr friend auto tag_invoke(types::Tag<serializable>, JsonFormat, InPlaceType<Value>) -> bool { return true; }
377
378 template<concepts::Encoding Enc, concepts::SameAs<InPlaceType<Value>> X = InPlaceType<Value>,
379 concepts::SameAs<bool> B = bool,
380 concepts::SameAs<types::Tag<format::formatter_in_place>> Tag = types::Tag<format::formatter_in_place>>
381 constexpr friend auto tag_invoke(Tag, X, format::FormatParseContext<Enc>& parse_context, B debug) {
382 return format::formatter<container::StringView>(parse_context, debug) %
383 [](concepts::CopyConstructible auto formatter) {
384 return [=](concepts::FormatContext auto& context, Value const& value) {
385 auto string = serialization::to_json_string(value, JsonSerializerConfig().pretty());
386 if (!string) {
387 return formatter(context, "[<JSON serializer error>]"_sv);
388 }
389 return formatter(context, string->view());
390 };
391 };
392 }
393
394 constexpr friend auto operator==(Value const& a, container::StringView view) -> bool {
395 return a.as_string() == view;
396 }
397 constexpr friend auto operator<=>(Value const& a, container::StringView view) {
398 constexpr auto string_index = usize(3);
399 if (auto result = a.index() <=> string_index; result != 0) {
400 return result;
401 }
402 return *a.as_string() <=> view;
403 }
404
405 constexpr auto force_array() -> Array& {
406 if (!is_array()) {
407 *this = Array {};
408 }
409 return as_array().value();
410 }
411
412 constexpr auto force_object() -> Object& {
413 if (!is_object()) {
414 *this = Object {};
415 }
416 return as_object().value();
417 }
418};
419}
420
421namespace di {
422namespace json = serialization::json;
423}
constexpr auto front()
Definition constant_vector_interface.h:44
constexpr auto back()
Definition constant_vector_interface.h:47
constexpr void clear()
Definition map_interface.h:51
constexpr auto size() const -> usize
Definition rb_tree.h:79
constexpr auto empty() const -> bool
Definition rb_tree.h:80
Definition tree_map.h:80
Definition vector_forward_declaration.h:8
Definition format_parse_context.h:14
Definition json_serializer.h:36
Definition json_value.h:107
constexpr auto try_emplace(U &&key, Args &&... args) -> decltype(auto)
Definition json_value.h:238
constexpr auto operator[](String const &key) -> decltype(auto)
Definition json_value.h:152
constexpr auto operator[](usize index) const -> Value const &
Definition json_value.h:344
constexpr auto insert_or_assign(U &&key, V &&value) -> decltype(auto)
Definition json_value.h:256
constexpr auto size() const -> usize
Definition json_value.h:273
constexpr auto as_array() -> vocab::Optional< Array & >
Definition json_value.h:146
constexpr auto is_string() const -> bool
Definition json_value.h:129
constexpr friend auto tag_invoke(Tag, InPlaceType< Value >, Args &&... args)
Definition json_value.h:115
constexpr auto front() -> Optional< Value & >
Definition json_value.h:300
constexpr auto is_integer() const -> bool
Definition json_value.h:127
constexpr auto operator[](String &&key) -> decltype(auto)
Definition json_value.h:153
constexpr auto is_true() const -> bool
Definition json_value.h:138
constexpr auto at(String const &key) -> Optional< Value & >
Definition json_value.h:163
constexpr auto try_emplace(String const &key, Args &&... args) -> decltype(auto)
Definition json_value.h:227
constexpr auto as_object() const -> vocab::Optional< Object const & >
Definition json_value.h:149
constexpr auto as_boolean() const -> vocab::Optional< Bool >
Definition json_value.h:133
constexpr friend auto tag_invoke(types::Tag< serializable >, JsonFormat, InPlaceType< Value >) -> bool
Definition json_value.h:376
constexpr auto push_back(Value &&value) -> decltype(auto)
Definition json_value.h:358
constexpr auto is_boolean() const -> bool
Definition json_value.h:126
constexpr auto as_array() const -> vocab::Optional< Array const & >
Definition json_value.h:147
constexpr auto erase(String const &key) -> size_t
Definition json_value.h:207
constexpr auto at(U &&key) -> Optional< Value & >
Definition json_value.h:176
constexpr auto operator[](usize index) -> Value &
Definition json_value.h:343
constexpr auto pop_back() -> Optional< Value >
Definition json_value.h:359
constexpr auto as_object() -> vocab::Optional< Object & >
Definition json_value.h:148
constexpr auto as_string() -> vocab::Optional< String & >
Definition json_value.h:144
constexpr auto is_false() const -> bool
Definition json_value.h:139
constexpr auto is_number() const -> bool
Definition json_value.h:128
constexpr auto is_null() const -> bool
Definition json_value.h:125
constexpr friend auto operator==(Value const &a, container::StringView view) -> bool
Definition json_value.h:394
constexpr friend auto operator<=>(Value const &a, container::StringView view)
Definition json_value.h:397
constexpr auto insert_or_assign(String const &key, V &&value) -> decltype(auto)
Definition json_value.h:245
constexpr friend auto tag_invoke(types::Tag< serialize >, JsonFormat, S &serializer, Value const &value) -> meta::SerializeResult< S >
Definition json_value.h:367
constexpr auto at(usize index) const -> Optional< Value const & >
Definition json_value.h:351
constexpr auto is_object() const -> bool
Definition json_value.h:131
constexpr void clear()
Definition json_value.h:287
constexpr auto at(String const &key) const -> Optional< Value const & >
Definition json_value.h:168
constexpr auto contains(String const &key) const -> bool
Definition json_value.h:190
constexpr auto is_array() const -> bool
Definition json_value.h:130
constexpr auto front() const -> Optional< Value const & >
Definition json_value.h:310
constexpr auto at(usize index) -> Optional< Value & >
Definition json_value.h:346
constexpr auto back() const -> Optional< Value const & >
Definition json_value.h:331
constexpr auto at(U &&key) const -> Optional< Value const & >
Definition json_value.h:183
constexpr auto as_integer() const -> vocab::Optional< Number >
Definition json_value.h:141
constexpr auto empty() const -> bool
Definition json_value.h:260
constexpr auto as_string() const -> vocab::Optional< String const & >
Definition json_value.h:145
constexpr auto insert_or_assign(String &&key, V &&value) -> decltype(auto)
Definition json_value.h:250
constexpr auto as_number() const -> vocab::Optional< Number >
Definition json_value.h:142
constexpr auto erase(U &&key) -> size_t
Definition json_value.h:216
constexpr auto contains(U &&key) const -> bool
Definition json_value.h:198
constexpr auto try_emplace(String &&key, Args &&... args) -> decltype(auto)
Definition json_value.h:232
constexpr friend auto tag_invoke(Tag, X, format::FormatParseContext< Enc > &parse_context, B debug)
Definition json_value.h:381
constexpr auto back() -> Optional< Value & >
Definition json_value.h:321
Definition optional_forward_declaration.h:5
Definition tuple_forward_declaration.h:5
Definition variant_forward_declaration.h:6
constexpr auto index() const -> size_t
Definition variant.h:173
Definition operations.h:11
Definition operations.h:34
Definition create.h:10
Definition format_context.h:9
Definition impl.h:7
string::StringViewImpl< string::Utf8Encoding > StringView
Definition string_view.h:12
string::StringImpl< string::Utf8Encoding > String
Definition string.h:11
constexpr auto formatter(FormatParseContext< Enc > &parse_context, bool debug=false)
Definition formatter.h:27
constexpr auto overload
Definition overload.h:28
meta::WriterResult< void, decltype(util::declval< S >().writer())> SerializeResult
Definition serialize.h:60
Definition json_value.h:26
constexpr auto null
Definition json_value.h:51
container::String String
Definition json_value.h:58
container::TreeMap< container::String, Value > Object
Definition json_value.h:60
i64 Number
Definition json_value.h:56
bool Bool
Definition json_value.h:53
vocab::Tuple< String, Value > KeyValue
Definition json_value.h:61
container::Vector< Value > Array
Definition json_value.h:59
Definition binary_deserializer.h:33
constexpr auto serialize
Definition serialize.h:130
constexpr auto to_json_string
Definition json_serializer.h:383
constexpr auto serializer
Definition serialize.h:43
size_t usize
Definition integers.h:33
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
__INT64_TYPE__ i64
Definition integers.h:17
auto declval() -> meta::AddRValueReference< T >
Definition declval.h:8
constexpr auto create(Args &&... args)
Definition create.h:21
Definition lazy.h:165
constexpr auto get_if(Var &&variant) -> Optional< meta::RemoveRValueReference< Res > >
Definition get_if.h:13
constexpr auto visit(Vis &&visitor, Vars &&... variants) -> R
Definition visit.h:39
constexpr auto holds_alternative
Definition holds_alternative.h:21
Definition zstring_parser.h:9
constexpr auto as_fallible
Definition as_fallible.h:26
constexpr auto try_infallible
Definition try_infallible.h:31
Definition json_serializer.h:357
Definition json_value.h:29
constexpr friend auto tag_invoke(types::Tag< serialization::serialize >, JsonFormat, auto &serializer, Null)
Definition json_value.h:43
auto operator<=>(Null const &) const =default
constexpr friend auto tag_invoke(types::Tag< format::formatter_in_place >, InPlaceType< Null >, format::FormatParseContext< Enc > &parse_context, bool debug)
Definition json_value.h:33
auto operator==(Null const &) const -> bool=default
Definition in_place_type.h:5