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