di 0.1.0
Loading...
Searching...
No Matches
json_deserializer.h
Go to the documentation of this file.
1#pragma once
2
10#include "di/io/prelude.h"
11#include "di/io/string_reader.h"
12#include "di/meta/core.h"
13#include "di/meta/operations.h"
14#include "di/parser/parse.h"
16#include "di/platform/prelude.h"
23#include "di/types/prelude.h"
24#include "di/util/exchange.h"
33
34namespace di::serialization {
35namespace detail {
36 template<typename S, typename T>
37 struct AllDeserializable {
38 constexpr static auto value = false;
39 };
40
41 template<typename S, typename... Types>
42 struct AllDeserializable<S, meta::List<Types...>> {
43 constexpr static auto value = (concepts::Deserializable<Types, S> && ...);
44 };
45
46 template<typename S, concepts::TypeList T>
47 constexpr static auto all_deserializable = AllDeserializable<S, T>::value;
48}
49
55template<concepts::Impl<io::Reader> Reader>
57private:
58 template<typename T = void>
59 using Result = meta::ReaderResult<T, Reader>;
60
61public:
63
64 template<typename T>
66 constexpr explicit JsonDeserializer(T&& reader) : m_reader(util::forward<T>(reader)) {}
67
68 constexpr auto deserialize(InPlaceType<json::Value>) -> Result<json::Value> {
69 auto result = DI_TRY(deserialize_value());
70 DI_TRY(skip_whitespace());
71 return result;
72 }
73
74 template<typename T, concepts::InstanceOf<reflection::Fields> M>
75 constexpr auto deserialize(InPlaceType<T>, M fields) -> Result<T> {
76 // NOTE: for now, this requires T be default constructible.
77 auto result = T {};
78
79 DI_TRY(skip_whitespace());
80 DI_TRY(expect('{'));
81
82 auto first = true;
83 for (;;) {
84 DI_TRY(skip_whitespace());
85 auto code_point = DI_TRY(peek_next_code_point());
86 if (!code_point) {
87 return vocab::Unexpected(BasicError::InvalidArgument);
88 }
89 if (*code_point == U'}') {
90 break;
91 }
92 if (!util::exchange(first, false)) {
93 DI_TRY(expect(U','));
94 }
95 auto key = DI_TRY(deserialize_string());
96 DI_TRY(skip_whitespace());
97 DI_TRY(expect(U':'));
98 DI_TRY(skip_whitespace());
99
100 auto found = false;
101 DI_TRY(vocab::tuple_sequence<Result<void>>(
102 [&](auto field) -> Result<void> {
104 using Value = meta::Type<decltype(field)>;
105 if constexpr (concepts::Optional<Value>) {
107 } else {
109 }
110 found = true;
111 }
112 return {};
113 },
114 fields));
115 if (!found) {
116 return vocab::Unexpected(BasicError::InvalidArgument);
117 }
118 }
119
120 DI_TRY(expect('}'));
121 DI_TRY(skip_whitespace());
122 return result;
123 }
124
125 template<typename T, concepts::InstanceOf<reflection::Enumerators> M>
126 constexpr auto deserialize(InPlaceType<T>, M enumerators) -> Result<T> {
127 DI_TRY(skip_whitespace());
128 auto string = DI_TRY(deserialize_string());
129 DI_TRY(skip_whitespace());
130 auto result = T(0);
131 auto found = false;
132
134 [&](auto enumerator) {
136 result = T(enumerator.value);
137 found = true;
138 }
139 },
140 enumerators);
141
142 if (!found) {
143 return vocab::Unexpected(BasicError::InvalidArgument);
144 }
145 return result;
146 }
147
148 template<typename T, concepts::InstanceOf<reflection::Atom> M>
149 requires(M::is_bool() || M::is_integer() || M::is_string())
150 constexpr auto deserialize(InPlaceType<T>, M) -> Result<T> {
151 if constexpr (M::is_bool()) {
152 auto result = DI_TRY(deserialize_bool());
153 DI_TRY(skip_whitespace());
154 return result;
155 } else if constexpr (M::is_integer()) {
156 auto result = DI_TRY(deserialize_number(in_place_type<T>));
157 DI_TRY(skip_whitespace());
158 return result;
159 } else if constexpr (M::is_string()) {
160 auto result = DI_TRY(deserialize_string());
161 DI_TRY(skip_whitespace());
162 return result;
163 }
164 }
165
166 template<typename T, concepts::InstanceOf<reflection::Atom> M>
167 constexpr auto deserialize(InPlaceType<T>, M) -> Result<T>
168 requires(M::is_custom_atom() && requires { di::parse<T>(di::StringView()); })
169 {
170 auto string = DI_TRY(deserialize_string());
171 auto result = DI_TRY(di::parse<T>(string.view()));
172 return result;
173 }
174
175 template<typename T, concepts::InstanceOf<reflection::Atom> M>
176 requires(M::is_tuple() && detail::all_deserializable<JsonDeserializer, meta::TupleElements<T>>)
177 constexpr auto deserialize(InPlaceType<T>, M) -> Result<T> {
178 // NOTE: for now, this requires T be default constructible.
179 auto result = T {};
180
181 DI_TRY(skip_whitespace());
182 DI_TRY(expect('['));
183
184 auto first = true;
186 [&]<typename Value>(Value& value) -> Result<> {
187 DI_TRY(skip_whitespace());
188 auto code_point = DI_TRY(peek_next_code_point());
189 if (!code_point) {
190 return vocab::Unexpected(BasicError::InvalidArgument);
191 }
192 // Indicates we've ran out of arguments
193 if (*code_point == U']') {
194 return vocab::Unexpected(BasicError::InvalidArgument);
195 }
196 if (!util::exchange(first, false)) {
197 DI_TRY(expect(U','));
198 }
199
201 return {};
202 },
203 result));
204
205 DI_TRY(skip_whitespace());
206 DI_TRY(expect(']'));
207 DI_TRY(skip_whitespace());
208 return result;
209 }
210
211 template<typename T, concepts::InstanceOf<reflection::Atom> M>
212 requires(M::is_variant() && detail::all_deserializable<JsonDeserializer, meta::VariantTypes<T>>)
213 constexpr auto deserialize(InPlaceType<T>, M) -> Result<T> {
214 constexpr auto possible_keys = []<typename... Types>(meta::List<Types...>) {
217
218 DI_TRY(skip_whitespace());
219 DI_TRY(expect('{'));
220
221 auto key = DI_TRY(deserialize_string());
222 DI_TRY(skip_whitespace());
223 DI_TRY(expect(U':'));
224 DI_TRY(skip_whitespace());
225
226 auto it = di::find(possible_keys, key);
227 if (it == possible_keys.end()) {
228 return di::Unexpected(di::BasicError::InvalidArgument);
229 }
230
232 usize(it - possible_keys.begin()), [&]<usize index>(Constexpr<index>) -> Result<T> {
233 using Value = meta::At<meta::VariantTypes<T>, index>;
234 return serialization::deserialize<Value>(*this);
235 }));
236
237 DI_TRY(skip_whitespace());
238 DI_TRY(expect('}'));
239 DI_TRY(skip_whitespace());
240 return result;
241 }
242
243 template<typename T, concepts::InstanceOf<reflection::Atom> M, typename U = meta::Type<meta::RemoveCVRef<T>>>
244 requires(M::is_box() && concepts::Deserializable<U, JsonDeserializer>)
245 constexpr auto deserialize(InPlaceType<T>, M) -> Result<T> {
246 DI_TRY(skip_whitespace());
247
248 // First check for null, then parse the underlying type.
249 auto code_point = DI_TRY(peek_next_code_point());
250 if (code_point == U'n') {
251 DI_TRY(deserialize_null());
252 return nullptr;
253 }
255 }
256
257 template<typename T, concepts::InstanceOf<reflection::Atom> M>
259 constexpr auto deserialize(InPlaceType<T>, M) -> Result<T> {
260 auto result = T {};
261
262 DI_TRY(skip_whitespace());
263 DI_TRY(expect('['));
264
265 for (;;) {
266 DI_TRY(skip_whitespace());
267 auto code_point = DI_TRY(peek_next_code_point());
268 if (!code_point) {
269 return vocab::Unexpected(BasicError::InvalidArgument);
270 }
271 if (*code_point == U']') {
272 break;
273 }
274 if (!result.empty()) {
275 DI_TRY(expect(U','));
276 }
278 }
279
280 DI_TRY(expect(']'));
281 DI_TRY(skip_whitespace());
282 return result;
283 }
284
285 template<typename T, concepts::InstanceOf<reflection::Atom> M>
288 constexpr auto deserialize(InPlaceType<T>, M) -> Result<T> {
289 auto result = T {};
290
291 DI_TRY(skip_whitespace());
292 DI_TRY(expect('{'));
293
294 for (;;) {
295 DI_TRY(skip_whitespace());
296 auto code_point = DI_TRY(peek_next_code_point());
297 if (!code_point) {
298 return vocab::Unexpected(BasicError::InvalidArgument);
299 }
300 if (*code_point == U'}') {
301 break;
302 }
303 if (!result.empty()) {
304 DI_TRY(expect(U','));
305 }
306 auto key = DI_TRY(deserialize_string());
307 DI_TRY(skip_whitespace());
308 DI_TRY(expect(U':'));
309 DI_TRY(skip_whitespace());
311 result.insert_or_assign(util::move(key), util::move(value));
312 }
313
314 DI_TRY(expect('}'));
315 DI_TRY(skip_whitespace());
316 return result;
317 }
318
319 constexpr auto deserialize(InPlaceType<json::Null>) -> Result<json::Null> {
320 auto result = DI_TRY(deserialize_null());
321 DI_TRY(skip_whitespace());
322 return result;
323 }
324
325 constexpr auto reader() & -> Reader& { return m_reader; }
326 constexpr auto reader() const& -> Reader const& { return m_reader; }
327 constexpr auto reader() && -> Reader&& { return util::move(*this).m_reader; }
328
329private:
330 constexpr static auto is_whitespace(c32 code_point) -> bool {
331 return code_point == ' ' || code_point == '\t' || code_point == '\n' || code_point == '\r';
332 }
333
334 constexpr auto expect(c32 expected) -> Result<void> {
335 auto code_point = DI_TRY(next_code_point());
336 if (!code_point || *code_point != expected) {
337 return vocab::Unexpected(BasicError::InvalidArgument);
338 }
339 return {};
340 }
341
342 constexpr auto fill_next_code_point() -> Result<void> {
343 // FIXME: handle UTF-8.
344 auto byte = vocab::Array<types::byte, 1> {};
345 auto nread = DI_TRY(io::read_some(m_reader, byte));
346 if (nread == 0) {
347 m_at_end = true;
348 }
349 m_next_code_point = c32(byte[0]);
350 return {};
351 }
352
353 constexpr auto peek_next_code_point() -> Result<vocab::Optional<c32>> {
354 if (m_at_end) {
355 return vocab::nullopt;
356 }
357 if (!m_next_code_point) {
358 DI_TRY(fill_next_code_point());
359 if (m_at_end) {
360 return vocab::nullopt;
361 }
362 }
363 return *m_next_code_point;
364 }
365
366 constexpr void consume() { m_next_code_point = vocab::nullopt; }
367
368 constexpr auto next_code_point() -> Result<vocab::Optional<c32>> {
369 if (m_at_end) {
370 return vocab::nullopt;
371 }
372 if (!m_next_code_point) {
373 DI_TRY(fill_next_code_point());
374 if (m_at_end) {
375 return vocab::nullopt;
376 }
377 }
378 return *util::exchange(m_next_code_point, vocab::nullopt);
379 }
380
381 constexpr auto require_next_code_point() -> Result<c32> {
382 auto code_point = DI_TRY(next_code_point());
383 if (!code_point) {
384 return vocab::Unexpected(BasicError::InvalidArgument);
385 }
386 return *code_point;
387 }
388
389 constexpr auto skip_whitespace() -> Result<void> {
390 for (;;) {
391 auto code_point = DI_TRY(peek_next_code_point());
392 if (!code_point || !is_whitespace(*code_point)) {
393 return {};
394 }
395 consume();
396 }
397 }
398
399 constexpr auto deserialize_value() -> Result<json::Value> {
400 DI_TRY(skip_whitespace());
401
402 auto code_point = DI_TRY(peek_next_code_point());
403 if (!code_point) {
404 return vocab::Unexpected(BasicError::InvalidArgument);
405 }
406
407 switch (*code_point) {
408 case U'n':
409 return deserialize_null();
410 case U't':
411 return deserialize_true();
412 case U'f':
413 return deserialize_false();
414 case U'"':
415 return deserialize_string();
416 case U'-':
417 case U'0':
418 case U'1':
419 case U'2':
420 case U'3':
421 case U'4':
422 case U'5':
423 case U'6':
424 case U'7':
425 case U'8':
426 case U'9':
427 return deserialize_number(in_place_type<json::Number>);
428 case U'{':
429 return deserialize_object();
430 case U'[':
431 return deserialize_array();
432 default:
433 return vocab::Unexpected(BasicError::InvalidArgument);
434 }
435 }
436
437 constexpr auto deserialize_null() -> Result<json::Null> {
438 DI_TRY(skip_whitespace());
439
440 DI_TRY(expect(U'n'));
441 DI_TRY(expect(U'u'));
442 DI_TRY(expect(U'l'));
443 DI_TRY(expect(U'l'));
444 return json::null;
445 }
446
447 constexpr auto deserialize_bool() -> Result<json::Bool> {
448 DI_TRY(skip_whitespace());
449
450 auto code_point = DI_TRY(require_next_code_point());
451 switch (code_point) {
452 case U't':
453 DI_TRY(expect(U'r'));
454 DI_TRY(expect(U'u'));
455 DI_TRY(expect(U'e'));
456 return true;
457 case U'f':
458 DI_TRY(expect(U'a'));
459 DI_TRY(expect(U'l'));
460 DI_TRY(expect(U's'));
461 DI_TRY(expect(U'e'));
462 return false;
463 default:
464 return vocab::Unexpected(BasicError::InvalidArgument);
465 }
466 }
467
468 constexpr auto deserialize_true() -> Result<json::Bool> {
469 DI_TRY(skip_whitespace());
470 DI_TRY(expect(U't'));
471 DI_TRY(expect(U'r'));
472 DI_TRY(expect(U'u'));
473 DI_TRY(expect(U'e'));
474 return true;
475 }
476
477 constexpr auto deserialize_false() -> Result<json::Bool> {
478 DI_TRY(skip_whitespace());
479 DI_TRY(expect(U'f'));
480 DI_TRY(expect(U'a'));
481 DI_TRY(expect(U'l'));
482 DI_TRY(expect(U's'));
483 DI_TRY(expect(U'e'));
484 return false;
485 }
486
487 constexpr auto from_hex_digit(c32 code_point) -> Result<u16> {
488 if (('0'_m - '9'_m)(code_point)) {
489 return u16(code_point - '0');
490 }
491 if (('A'_m - 'F'_m)(code_point)) {
492 return u16(10u + (code_point - 'A'));
493 }
494 if (('a'_m - 'f'_m)(code_point)) {
495 return u16(10u + (code_point - 'a'));
496 }
497 return vocab::Unexpected(BasicError::InvalidArgument);
498 }
499
500 constexpr auto parse_four_hex_digits() -> Result<u16> {
501 auto result = u16(0);
502 result |= DI_TRY(from_hex_digit(DI_TRY(require_next_code_point()))) << 12;
503 result |= DI_TRY(from_hex_digit(DI_TRY(require_next_code_point()))) << 8;
504 result |= DI_TRY(from_hex_digit(DI_TRY(require_next_code_point()))) << 4;
505 result |= DI_TRY(from_hex_digit(DI_TRY(require_next_code_point()))) << 0;
506 return result;
507 }
508
509 constexpr static auto is_high_surrogate(u16 code_unit) -> bool { return (code_unit >> 10) == 0b110110u; }
510 constexpr static auto is_low_surrogate(u16 code_unit) -> bool { return (code_unit >> 10) == 0b110111u; }
511
512 constexpr auto deserialize_string() -> Result<json::String> {
513 DI_TRY(skip_whitespace());
514 DI_TRY(expect(U'"'));
515
516 auto string = json::String {};
517 for (;;) {
518 auto code_point = DI_TRY(next_code_point());
519 if (!code_point || *code_point < 0x20) {
520 return vocab::Unexpected(BasicError::InvalidArgument);
521 }
522 if (code_point == U'\\') {
523 auto escaped = DI_TRY(require_next_code_point());
524 switch (escaped) {
525 case U'"':
526 string.push_back(U'"');
527 continue;
528 case U'\\':
529 string.push_back(U'\\');
530 continue;
531 case U'/':
532 string.push_back(U'/');
533 continue;
534 case U'b':
535 string.push_back(U'\b');
536 continue;
537 case U'f':
538 string.push_back(U'\f');
539 continue;
540 case U'n':
541 string.push_back(U'\n');
542 continue;
543 case U'r':
544 string.push_back(U'\r');
545 continue;
546 case U't':
547 string.push_back(U'\t');
548 continue;
549 case U'u': {
550 // Escaped unicode sequences are encoded via UTF-16, despite the underlying data being
551 // encoded in UTF-8.
552 auto code_point = DI_TRY(parse_four_hex_digits());
553 if (is_high_surrogate(code_point)) {
554 // Require a curresponding escaped low surrogate
555 DI_TRY(expect(U'\\'));
556 DI_TRY(expect(U'u'));
557 auto low_code_point = DI_TRY(parse_four_hex_digits());
558 if (!is_low_surrogate(low_code_point)) {
559 return vocab::Unexpected(BasicError::InvalidArgument);
560 }
561 auto actual_code_point =
562 c32((code_point - 0xD800u) << 10) + c32(low_code_point - 0xDC00u) + c32(0x10000);
563 string.push_back(actual_code_point);
564 continue;
565 }
566 if (is_low_surrogate(code_point)) {
567 return vocab::Unexpected(BasicError::InvalidArgument);
568 }
569 string.push_back(c32(code_point));
570 continue;
571 }
572 default:
573 return vocab::Unexpected(BasicError::InvalidArgument);
574 }
575 }
576
577 if (*code_point == U'"') {
578 break;
579 }
580 string.push_back(*code_point);
581 }
582 return string;
583 }
584
585 template<concepts::Integer T>
586 constexpr auto deserialize_number(InPlaceType<T>) -> Result<json::Number> {
587 DI_TRY(skip_whitespace());
588 auto first_code_point = DI_TRY(require_next_code_point());
589
590 auto string = json::String {};
591 if (first_code_point == U'-') {
592 string.push_back(first_code_point);
593 first_code_point = DI_TRY(require_next_code_point());
594 if (first_code_point < U'0' || first_code_point > U'9') {
595 return vocab::Unexpected(BasicError::InvalidArgument);
596 }
597 }
598 if (first_code_point == U'0') {
599 return 0;
600 }
601
602 string.push_back(first_code_point);
603
604 for (;;) {
605 auto code_point = DI_TRY(peek_next_code_point());
606 if (!code_point) {
607 break;
608 }
609
610 if (*code_point < U'0' || *code_point > U'9') {
611 break;
612 }
613
614 string.push_back(*code_point);
615 consume();
616 }
617
618 // FIXME: handle decimal point and exponent for floating point numbers.
619 auto result = parser::parse<T>(string);
620 if (!result) {
621 return vocab::Unexpected(BasicError::InvalidArgument);
622 }
623 return *result;
624 }
625
626 constexpr auto deserialize_array() -> Result<json::Array> {
627 DI_TRY(skip_whitespace());
628 DI_TRY(expect(U'['));
629
630 auto array = json::Array {};
631 for (;;) {
632 DI_TRY(skip_whitespace());
633 auto code_point = DI_TRY(peek_next_code_point());
634 if (!code_point) {
635 return vocab::Unexpected(BasicError::InvalidArgument);
636 }
637 if (*code_point == U']') {
638 break;
639 }
640 if (!array.empty()) {
641 DI_TRY(expect(U','));
642 }
643 array.push_back(DI_TRY(deserialize_value()));
644 }
645
646 DI_TRY(expect(U']'));
647 return array;
648 }
649
650 constexpr auto deserialize_object() -> Result<json::Object> {
651 DI_TRY(skip_whitespace());
652 DI_TRY(expect(U'{'));
653
654 auto object = json::Object {};
655 for (;;) {
656 DI_TRY(skip_whitespace());
657 auto code_point = DI_TRY(peek_next_code_point());
658 if (!code_point) {
659 return vocab::Unexpected(BasicError::InvalidArgument);
660 }
661 if (*code_point == U'}') {
662 break;
663 }
664 if (!object.empty()) {
665 DI_TRY(expect(U','));
666 DI_TRY(skip_whitespace());
667 }
668 auto key = DI_TRY(deserialize_string());
669 DI_TRY(skip_whitespace());
670 DI_TRY(expect(U':'));
671 auto value = DI_TRY(deserialize_value());
672 object.insert_or_assign(util::move(key), util::move(value));
673 }
674
675 DI_TRY(expect(U'}'));
676 return object;
677 }
678
679 Reader m_reader;
680 vocab::Optional<c32> m_next_code_point;
681 bool m_at_end { false };
682};
683
684template<typename T>
686
687namespace detail {
688 template<typename T>
689 struct FromJsonStringFunction {
690 template<typename... Args>
693 constexpr auto operator()(container::StringView view, Args&&... args) const {
694 return serialization::deserialize_string<T>(json_format, view, util::forward<Args>(args)...);
695 }
696 };
697}
698
699template<concepts::Deserializable<JsonDeserializer<StringReader<container::StringView>>> T = json::Value>
700constexpr inline auto from_json_string = detail::FromJsonStringFunction<T> {};
701
702namespace detail {
703 template<typename T>
704 struct DeserializeJsonFunction {
705 template<concepts::Impl<io::Reader> Reader, typename... Args>
707 Args...> &&
709 constexpr auto operator()(Reader&& reader, Args&&... args) const {
710 return serialization::deserialize<T>(json_format, ref(reader), util::forward<Args>(args)...);
711 }
712 };
713}
714
715template<typename T = json::Value>
716constexpr inline auto deserialize_json = detail::DeserializeJsonFunction<T> {};
717}
718
719namespace di {
720inline namespace literals {
721 inline namespace json_literals {
722 namespace detail {
723 template<container::FixedString string>
724 consteval auto valid_json_literal() -> bool {
725 // NOTE: GCC does not think that the following is a constant expression, but clang does.
726#ifdef DI_CLANG
728 return serialization::from_json_string<>(string_view).has_value();
729#endif
730 return true;
731 }
732 }
733
734 template<container::FixedString string>
735 requires(detail::valid_json_literal<string>())
736 constexpr auto operator""_json() {
738 return *serialization::from_json_string<>(string_view);
739 }
740 }
741}
742}
743
744#if !defined(DI_NO_GLOBALS) && !defined(DI_NO_GLOBAL_JSON_LITERALS)
745using namespace di::literals::json_literals;
746#endif
747
748namespace di {
750
753}
constexpr JsonDeserializer(T &&reader)
Definition json_deserializer.h:66
constexpr auto push_back(CodePoint code_point)
Definition mutable_string_interface.h:147
Definition string_reader.h:18
A deserializer for the JSON format.
Definition json_deserializer.h:56
constexpr auto reader() &-> Reader &
Definition json_deserializer.h:325
constexpr auto deserialize(InPlaceType< T >, M) -> Result< T >
Definition json_deserializer.h:150
constexpr auto deserialize(InPlaceType< T >, M) -> Result< T >
Definition json_deserializer.h:213
constexpr auto deserialize(InPlaceType< T >, M fields) -> Result< T >
Definition json_deserializer.h:75
constexpr auto deserialize(InPlaceType< T >, M) -> Result< T >
Definition json_deserializer.h:259
constexpr auto deserialize(InPlaceType< T >, M enumerators) -> Result< T >
Definition json_deserializer.h:126
constexpr JsonDeserializer(T &&reader)
Definition json_deserializer.h:66
constexpr auto deserialize(InPlaceType< T >, M) -> Result< T > requires(M::is_custom_atom() &&
Definition json_deserializer.h:167
constexpr auto deserialize(InPlaceType< T >, M) -> Result< T >
Definition json_deserializer.h:245
JsonFormat DeserializationFormat
Definition json_deserializer.h:62
auto result
Definition json_deserializer.h:171
constexpr auto reader() &&-> Reader &&
Definition json_deserializer.h:327
constexpr auto reader() const &-> Reader const &
Definition json_deserializer.h:326
constexpr auto deserialize(InPlaceType< T >, M) -> Result< T >
Definition json_deserializer.h:177
constexpr auto deserialize(InPlaceType< json::Null >) -> Result< json::Null >
Definition json_deserializer.h:319
constexpr auto deserialize(InPlaceType< T >, M) -> Result< T >
Definition json_deserializer.h:288
constexpr auto deserialize(InPlaceType< json::Value >) -> Result< json::Value >
Definition json_deserializer.h:68
Definition unexpected.h:14
Definition operations.h:11
Definition deserialize.h:153
Definition vocab.h:77
Definition core.h:114
#define DI_TRY(...)
Definition monad_try.h:13
#define TRY
Definition monad_try.h:23
string::StringViewImpl< string::Utf8Encoding > StringView
Definition string_view.h:12
constexpr auto fixed_string_to_utf8_string_view
Definition fixed_string_to_utf8_string_view.h:32
constexpr auto value
Definition value.h:34
constexpr auto index_dispatch
Definition index_dispatch.h:41
constexpr auto read_some
Definition reader.h:32
meta::List< ReadSome > Reader
Definition reader.h:34
Definition json_deserializer.h:721
T::Type Type
Definition core.h:26
constexpr usize Size
Definition list.h:114
meta::RemoveCVRef< T >::Value OptionalValue
Definition vocab.h:82
meta::LikeExpected< decltype(io::read_some(util::declval< Reader & >(), util::declval< Span< Byte > >())), T > ReaderResult
Definition reader.h:39
decltype(vocab::variant_types(in_place_type< meta::RemoveCVRef< T > >)) VariantTypes
Definition variant_types.h:24
decltype(vocab::tuple_element(types::in_place_type< meta::RemoveReference< T > >, c_< index >))::Type TupleElement
Definition tuple_element.h:21
IteratorValue< ContainerIterator< T > > ContainerValue
Definition container_value.h:8
constexpr auto code_point
Definition code_point_parser.h:35
constexpr auto parse
Definition parse.h:23
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
container::Vector< Value > Array
Definition json_value.h:59
Definition base64.h:16
constexpr auto from_json_string
Definition json_deserializer.h:700
JsonDeserializer(T &&) -> JsonDeserializer< T >
constexpr auto deserialize_json
Definition json_deserializer.h:716
constexpr auto json_format
Definition json_serializer.h:475
constexpr auto deserialize_string
Definition deserialize_string.h:27
constexpr auto deserialize
Definition deserialize.h:178
size_t usize
Definition integers.h:33
char32_t c32
Definition char.h:6
__UINT16_TYPE__ u16
Definition integers.h:10
constexpr auto exchange(T &object, U &&new_value) -> T
Definition exchange.h:8
Array(T, U...) -> Array< T, 1+sizeof...(U)>
Expected< T, Error > Result
Definition result.h:8
constexpr auto nullopt
Definition nullopt.h:15
constexpr auto tuple_sequence
Definition tuple_sequence.h:36
constexpr void tuple_for_each(F &&function, Tup &&tuple)
Definition tuple_for_each.h:22
Unexpected(E &&) -> Unexpected< meta::UnwrapRefDecay< E > >
Definition any_storable.h:9
constexpr auto empty
Definition empty.h:45
constexpr auto make_box
Definition box.h:169
constexpr auto ref
Definition reference_wrapper.h:98
constexpr auto find
Definition find.h:35
constexpr auto enumerator
Definition enumerator.h:40
constexpr auto field
Definition field.h:46
constexpr auto json_format
Definition json_serializer.h:475
constexpr auto in_place_type
Definition in_place_type.h:12
constexpr auto deserialize
Definition deserialize.h:178
constexpr auto parse
Definition parse.h:23
A wrapper for a constexpr value.
Definition constexpr.h:36
Definition core.h:5
Definition json_serializer.h:461
Definition in_place_type.h:5
Definition array.h:27