1extern crate alloc;
4
5pub mod object_key;
6pub mod record;
7pub mod tuple;
8pub mod union;
9pub mod variant_path;
10
11use indexmap::{IndexMap, IndexSet};
12pub use object_key::ParseObjectKey;
13pub use record::RecordParser;
14pub use tuple::TupleParser;
15pub use union::UnionParser;
16pub use variant_path::VariantPath;
17use alloc::format;
20use alloc::rc::Rc;
21use core::cell::RefCell;
22use num_bigint::BigInt;
23
24use core::marker::PhantomData;
25use std::collections::{BTreeMap, HashMap, HashSet};
26
27use crate::{
28 data_model::VariantRepr,
29 document::node::{Node, NodeArray},
30 identifier::IdentifierError,
31 prelude_internal::*,
32 value::ValueKind,
33};
34
35#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
47pub enum UnionTagMode {
48 #[default]
55 Eure,
56
57 Repr,
64}
65
66pub type AccessedSnapshot = (HashSet<String>, HashSet<Identifier>);
72
73#[derive(Debug, Clone)]
90pub struct AccessedSet(Rc<RefCell<Vec<AccessedSnapshot>>>);
91
92impl AccessedSet {
93 pub fn new() -> Self {
95 Self(Rc::new(RefCell::new(vec![(
97 HashSet::new(),
98 HashSet::new(),
99 )])))
100 }
101
102 pub fn add_field(&self, field: impl Into<String>) {
104 self.0
105 .borrow_mut()
106 .last_mut()
107 .unwrap()
108 .0
109 .insert(field.into());
110 }
111
112 pub fn add_ext(&self, ext: Identifier) {
114 self.0.borrow_mut().last_mut().unwrap().1.insert(ext);
115 }
116
117 pub fn has_field(&self, field: &str) -> bool {
119 self.0.borrow().last().unwrap().0.contains(field)
120 }
121
122 pub fn has_ext(&self, ext: &Identifier) -> bool {
124 self.0.borrow().last().unwrap().1.contains(ext)
125 }
126
127 pub fn push_snapshot(&self) {
130 let mut stack = self.0.borrow_mut();
131 let snapshot = stack.last().unwrap().clone();
132 let len = stack.len();
133 stack.insert(len - 1, snapshot);
134 }
136
137 pub fn restore_to_current_snapshot(&self) {
140 let mut stack = self.0.borrow_mut();
141 if stack.len() >= 2 {
142 let snapshot = stack[stack.len() - 2].clone();
143 *stack.last_mut().unwrap() = snapshot;
144 }
145 }
146
147 pub fn capture_current_state(&self) -> AccessedSnapshot {
149 self.0.borrow().last().unwrap().clone()
150 }
151
152 pub fn restore_to_state(&self, state: AccessedSnapshot) {
154 *self.0.borrow_mut().last_mut().unwrap() = state;
155 }
156
157 pub fn pop_and_restore(&self) {
160 let mut stack = self.0.borrow_mut();
161 if stack.len() >= 2 {
162 stack.pop(); }
164 }
165
166 pub fn pop_without_restore(&self) {
169 let mut stack = self.0.borrow_mut();
170 if stack.len() >= 2 {
171 let snapshot_idx = stack.len() - 2;
172 stack.remove(snapshot_idx); }
174 }
175}
176
177impl Default for AccessedSet {
178 fn default() -> Self {
179 Self::new()
180 }
181}
182
183#[derive(Debug, Clone, Copy, PartialEq, Eq)]
191pub enum ParserScope {
192 Record,
194 Extension,
196}
197
198#[derive(Debug, Clone)]
225pub struct FlattenContext {
226 accessed: AccessedSet,
227 scope: ParserScope,
228}
229
230impl FlattenContext {
231 pub fn new(accessed: AccessedSet, scope: ParserScope) -> Self {
233 Self { accessed, scope }
234 }
235
236 pub fn scope(&self) -> ParserScope {
238 self.scope
239 }
240
241 pub fn accessed_set(&self) -> &AccessedSet {
243 &self.accessed
244 }
245
246 pub fn add_field(&self, field: impl Into<String>) {
248 self.accessed.add_field(field);
249 }
250
251 pub fn add_ext(&self, ext: Identifier) {
253 self.accessed.add_ext(ext);
254 }
255
256 pub fn has_field(&self, field: &str) -> bool {
258 self.accessed.has_field(field)
259 }
260
261 pub fn has_ext(&self, ext: &Identifier) -> bool {
263 self.accessed.has_ext(ext)
264 }
265
266 pub fn push_snapshot(&self) {
268 self.accessed.push_snapshot();
269 }
270
271 pub fn restore_to_current_snapshot(&self) {
273 self.accessed.restore_to_current_snapshot();
274 }
275
276 pub fn capture_current_state(&self) -> AccessedSnapshot {
278 self.accessed.capture_current_state()
279 }
280
281 pub fn restore_to_state(&self, state: AccessedSnapshot) {
283 self.accessed.restore_to_state(state);
284 }
285
286 pub fn pop_and_restore(&self) {
288 self.accessed.pop_and_restore();
289 }
290
291 pub fn pop_without_restore(&self) {
293 self.accessed.pop_without_restore();
294 }
295}
296
297#[derive(Clone, Debug)]
306pub struct ParseContext<'doc> {
307 doc: &'doc EureDocument,
308 node_id: NodeId,
309 variant_path: Option<VariantPath>,
310 flatten_ctx: Option<FlattenContext>,
314 union_tag_mode: UnionTagMode,
316 accessed: AccessedSet,
318}
319
320impl<'doc> ParseContext<'doc> {
321 pub fn new(doc: &'doc EureDocument, node_id: NodeId) -> Self {
323 Self {
324 doc,
325 node_id,
326 variant_path: None,
327 flatten_ctx: None,
328 union_tag_mode: UnionTagMode::default(),
329 accessed: AccessedSet::new(),
330 }
331 }
332
333 pub fn with_union_tag_mode(
335 doc: &'doc EureDocument,
336 node_id: NodeId,
337 mode: UnionTagMode,
338 ) -> Self {
339 Self {
340 doc,
341 node_id,
342 variant_path: None,
343 flatten_ctx: None,
344 union_tag_mode: mode,
345 accessed: AccessedSet::new(),
346 }
347 }
348
349 pub fn with_flatten_ctx(
355 doc: &'doc EureDocument,
356 node_id: NodeId,
357 flatten_ctx: FlattenContext,
358 mode: UnionTagMode,
359 ) -> Self {
360 let accessed = flatten_ctx.accessed_set().clone();
362 Self {
363 doc,
364 node_id,
365 variant_path: None,
366 flatten_ctx: Some(flatten_ctx),
367 union_tag_mode: mode,
368 accessed,
369 }
370 }
371
372 pub fn flatten_ctx(&self) -> Option<&FlattenContext> {
374 self.flatten_ctx.as_ref()
375 }
376
377 pub fn is_flattened(&self) -> bool {
381 self.flatten_ctx.is_some()
382 }
383
384 pub fn parser_scope(&self) -> Option<ParserScope> {
390 self.flatten_ctx.as_ref().map(|fc| fc.scope())
391 }
392
393 pub fn node_id(&self) -> NodeId {
395 self.node_id
396 }
397
398 pub(crate) fn doc(&self) -> &'doc EureDocument {
400 self.doc
401 }
402
403 pub fn node(&self) -> &'doc Node {
405 self.doc.node(self.node_id)
406 }
407
408 pub(crate) fn at(&self, node_id: NodeId) -> Self {
410 Self {
411 doc: self.doc,
412 node_id,
413 variant_path: None,
414 flatten_ctx: None,
415 union_tag_mode: self.union_tag_mode,
416 accessed: AccessedSet::new(),
417 }
418 }
419
420 pub fn flatten(&self) -> Self {
437 if let Some(fc) = &self.flatten_ctx {
439 return Self {
440 doc: self.doc,
441 node_id: self.node_id,
442 variant_path: self.variant_path.clone(),
443 flatten_ctx: Some(fc.clone()),
444 union_tag_mode: self.union_tag_mode,
445 accessed: self.accessed.clone(),
446 };
447 }
448
449 let flatten_ctx = FlattenContext::new(self.accessed.clone(), ParserScope::Record);
451 Self {
452 doc: self.doc,
453 node_id: self.node_id,
454 variant_path: self.variant_path.clone(),
455 flatten_ctx: Some(flatten_ctx),
456 union_tag_mode: self.union_tag_mode,
457 accessed: self.accessed.clone(),
458 }
459 }
460
461 pub fn union_tag_mode(&self) -> UnionTagMode {
463 self.union_tag_mode
464 }
465
466 pub fn parse<T: ParseDocument<'doc>>(&self) -> Result<T, T::Error> {
468 T::parse(self)
469 }
470
471 pub fn parse_with<T: DocumentParser<'doc>>(
472 &self,
473 mut parser: T,
474 ) -> Result<T::Output, T::Error> {
475 parser.parse(self)
476 }
477
478 pub fn parse_union<T, E>(&self, repr: VariantRepr) -> Result<UnionParser<'doc, '_, T, E>, E>
486 where
487 E: From<ParseError>,
488 {
489 UnionParser::new(self, repr).map_err(Into::into)
490 }
491
492 pub fn parse_record(&self) -> Result<RecordParser<'doc>, ParseError> {
496 self.ensure_no_variant_path()?;
497 RecordParser::new(self)
498 }
499
500 pub fn parse_tuple(&self) -> Result<TupleParser<'doc>, ParseError> {
504 self.ensure_no_variant_path()?;
505 TupleParser::new(self)
506 }
507
508 pub fn parse_primitive(&self) -> Result<&'doc PrimitiveValue, ParseError> {
512 self.ensure_no_variant_path()?;
513 match &self.node().content {
514 NodeValue::Primitive(p) => Ok(p),
515 value => Err(ParseError {
516 node_id: self.node_id,
517 kind: handle_unexpected_node_value(value),
518 }),
519 }
520 }
521
522 pub(crate) fn accessed(&self) -> &AccessedSet {
528 &self.accessed
529 }
530
531 fn mark_ext_accessed(&self, ident: Identifier) {
533 self.accessed.add_ext(ident);
534 }
535
536 pub fn parse_ext<T>(&self, name: &str) -> Result<T, T::Error>
540 where
541 T: ParseDocument<'doc>,
542 T::Error: From<ParseError>,
543 {
544 self.parse_ext_with(name, T::parse)
545 }
546
547 pub fn parse_ext_with<T>(&self, name: &str, mut parser: T) -> Result<T::Output, T::Error>
549 where
550 T: DocumentParser<'doc>,
551 T::Error: From<ParseError>,
552 {
553 let ident: Identifier = name.parse().map_err(|e| ParseError {
554 node_id: self.node_id,
555 kind: ParseErrorKind::InvalidIdentifier(e),
556 })?;
557 self.mark_ext_accessed(ident.clone());
558 let ext_node_id = self
559 .node()
560 .extensions
561 .get(&ident)
562 .ok_or_else(|| ParseError {
563 node_id: self.node_id,
564 kind: ParseErrorKind::MissingExtension(name.to_string()),
565 })?;
566 let ctx = ParseContext::with_union_tag_mode(self.doc, *ext_node_id, self.union_tag_mode);
567 parser.parse(&ctx)
568 }
569
570 pub fn parse_ext_optional<T>(&self, name: &str) -> Result<Option<T>, T::Error>
574 where
575 T: ParseDocument<'doc>,
576 T::Error: From<ParseError>,
577 {
578 self.parse_ext_optional_with(name, T::parse)
579 }
580
581 pub fn parse_ext_optional_with<T>(
585 &self,
586 name: &str,
587 mut parser: T,
588 ) -> Result<Option<T::Output>, T::Error>
589 where
590 T: DocumentParser<'doc>,
591 T::Error: From<ParseError>,
592 {
593 let ident: Identifier = name.parse().map_err(|e| ParseError {
594 node_id: self.node_id,
595 kind: ParseErrorKind::InvalidIdentifier(e),
596 })?;
597 self.mark_ext_accessed(ident.clone());
598 match self.node().extensions.get(&ident) {
599 Some(ext_node_id) => {
600 let ctx =
601 ParseContext::with_union_tag_mode(self.doc, *ext_node_id, self.union_tag_mode);
602 Ok(Some(parser.parse(&ctx)?))
603 }
604 None => Ok(None),
605 }
606 }
607
608 pub fn ext(&self, name: &str) -> Result<ParseContext<'doc>, ParseError> {
613 let ident: Identifier = name.parse().map_err(|e| ParseError {
614 node_id: self.node_id,
615 kind: ParseErrorKind::InvalidIdentifier(e),
616 })?;
617 self.mark_ext_accessed(ident.clone());
618 let ext_node_id =
619 self.node()
620 .extensions
621 .get(&ident)
622 .copied()
623 .ok_or_else(|| ParseError {
624 node_id: self.node_id,
625 kind: ParseErrorKind::MissingExtension(name.to_string()),
626 })?;
627 Ok(ParseContext::with_union_tag_mode(
628 self.doc,
629 ext_node_id,
630 self.union_tag_mode,
631 ))
632 }
633
634 pub fn ext_optional(&self, name: &str) -> Option<ParseContext<'doc>> {
639 let ident: Identifier = name.parse().ok()?;
640 self.mark_ext_accessed(ident.clone());
641 self.node().extensions.get(&ident).map(|&node_id| {
642 ParseContext::with_union_tag_mode(self.doc, node_id, self.union_tag_mode)
643 })
644 }
645
646 pub fn deny_unknown_extensions(&self) -> Result<(), ParseError> {
651 if self.flatten_ctx.is_some() {
653 return Ok(());
654 }
655
656 for (ident, _) in self.node().extensions.iter() {
658 if !self.accessed.has_ext(ident) {
659 return Err(ParseError {
660 node_id: self.node_id,
661 kind: ParseErrorKind::UnknownExtension(ident.clone()),
662 });
663 }
664 }
665 Ok(())
666 }
667
668 pub fn unknown_extensions(
672 &self,
673 ) -> impl Iterator<Item = (&'doc Identifier, ParseContext<'doc>)> + '_ {
674 let doc = self.doc;
675 let mode = self.union_tag_mode;
676 let accessed = self.accessed.clone();
678 self.node()
679 .extensions
680 .iter()
681 .filter_map(move |(ident, &node_id)| {
682 if !accessed.has_ext(ident) {
683 Some((ident, ParseContext::with_union_tag_mode(doc, node_id, mode)))
684 } else {
685 None
686 }
687 })
688 }
689
690 pub fn flatten_ext(&self) -> ParseContext<'doc> {
700 let flatten_ctx = match &self.flatten_ctx {
702 Some(fc) => fc.clone(),
703 None => {
704 FlattenContext::new(self.accessed.clone(), ParserScope::Extension)
706 }
707 };
708
709 ParseContext::with_flatten_ctx(self.doc, self.node_id, flatten_ctx, self.union_tag_mode)
710 }
711
712 pub fn is_null(&self) -> bool {
714 matches!(
715 &self.node().content,
716 NodeValue::Primitive(PrimitiveValue::Null)
717 )
718 }
719
720 pub(crate) fn with_variant_rest(&self, rest: Option<VariantPath>) -> Self {
722 Self {
723 doc: self.doc,
724 node_id: self.node_id,
725 variant_path: rest,
726 flatten_ctx: self.flatten_ctx.clone(),
727 union_tag_mode: self.union_tag_mode,
728 accessed: self.accessed.clone(),
729 }
730 }
731
732 pub(crate) fn variant_path(&self) -> Option<&VariantPath> {
734 self.variant_path.as_ref()
735 }
736
737 fn ensure_no_variant_path(&self) -> Result<(), ParseError> {
739 if let Some(vp) = &self.variant_path
740 && !vp.is_empty()
741 {
742 return Err(ParseError {
743 node_id: self.node_id,
744 kind: ParseErrorKind::UnexpectedVariantPath(vp.clone()),
745 });
746 }
747 Ok(())
748 }
749}
750
751pub trait ParseDocument<'doc>: Sized {
775 type Error;
777
778 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error>;
780}
781
782fn handle_unexpected_node_value(node_value: &NodeValue) -> ParseErrorKind {
783 match node_value {
784 NodeValue::Hole(_) => ParseErrorKind::UnexpectedHole,
785 value => value
786 .value_kind()
787 .map(|actual| ParseErrorKind::TypeMismatch {
788 expected: ValueKind::Text,
789 actual,
790 })
791 .unwrap_or_else(|| ParseErrorKind::UnexpectedHole),
792 }
793}
794
795#[derive(Debug, thiserror::Error, Clone, PartialEq)]
796#[error("parse error: {kind}")]
797pub struct ParseError {
798 pub node_id: NodeId,
799 pub kind: ParseErrorKind,
800}
801
802#[derive(Debug, thiserror::Error, Clone, PartialEq)]
804pub enum ParseErrorKind {
805 #[error("unexpected uninitialized value")]
807 UnexpectedHole,
808
809 #[error("type mismatch: expected {expected}, got {actual}")]
811 TypeMismatch {
812 expected: ValueKind,
813 actual: ValueKind,
814 },
815
816 #[error("missing field: {0}")]
818 MissingField(String),
819
820 #[error("missing extension: ${0}")]
822 MissingExtension(String),
823
824 #[error("unknown variant: {0}")]
826 UnknownVariant(String),
827
828 #[error("value out of range: {0}")]
830 OutOfRange(String),
831
832 #[error("invalid {kind}: {reason}")]
838 InvalidPattern { kind: String, reason: String },
839
840 #[error("at {path}: {source}")]
842 Nested {
843 path: String,
844 #[source]
845 source: Box<ParseErrorKind>,
846 },
847
848 #[error("invalid identifier: {0}")]
850 InvalidIdentifier(#[from] IdentifierError),
851
852 #[error("unexpected tuple length: expected {expected}, got {actual}")]
854 UnexpectedTupleLength { expected: usize, actual: usize },
855
856 #[error("unknown field: {0}")]
858 UnknownField(String),
859
860 #[error("unknown extension: ${0}")]
862 UnknownExtension(Identifier),
863
864 #[error("invalid key type in record: expected string key, got {0:?}")]
866 InvalidKeyType(crate::value::ObjectKey),
867
868 #[error("no matching variant{}", variant.as_ref().map(|v| format!(" (variant: {})", v)).unwrap_or_default())]
870 NoMatchingVariant {
871 variant: Option<String>,
873 },
874
875 #[error("conflicting variant tags: $variant = {explicit}, repr = {repr}")]
877 ConflictingVariantTags { explicit: String, repr: String },
878
879 #[error("ambiguous union: {0:?}")]
881 AmbiguousUnion(Vec<String>),
882
883 #[error("literal value mismatch: expected {expected}, got {actual}")]
885 LiteralMismatch { expected: String, actual: String },
887
888 #[error("unexpected variant path: {0}")]
890 UnexpectedVariantPath(VariantPath),
891
892 #[error("$variant must be a string, got {0}")]
894 InvalidVariantType(ValueKind),
895
896 #[error("invalid $variant path syntax: {0}")]
898 InvalidVariantPath(String),
899
900 #[error(
903 "cannot parse record in extension scope: use #[eure(flatten)] instead of #[eure(flatten_ext)]"
904 )]
905 RecordInExtensionScope,
906}
907
908impl ParseErrorKind {
909 pub fn at(self, path: impl Into<String>) -> Self {
911 ParseErrorKind::Nested {
912 path: path.into(),
913 source: Box::new(self),
914 }
915 }
916}
917
918impl<'doc> EureDocument {
919 pub fn parse<T: ParseDocument<'doc>>(&'doc self, node_id: NodeId) -> Result<T, T::Error> {
921 self.parse_with(node_id, T::parse)
922 }
923
924 pub fn parse_with<T: DocumentParser<'doc>>(
925 &'doc self,
926 node_id: NodeId,
927 mut parser: T,
928 ) -> Result<T::Output, T::Error> {
929 parser.parse(&self.parse_context(node_id))
930 }
931
932 pub fn parse_context(&'doc self, node_id: NodeId) -> ParseContext<'doc> {
934 ParseContext::new(self, node_id)
935 }
936
937 pub fn parse_record(&'doc self, node_id: NodeId) -> Result<RecordParser<'doc>, ParseError> {
941 RecordParser::from_doc_and_node(self, node_id)
942 }
943
944 pub fn parse_extension_context(&'doc self, node_id: NodeId) -> ParseContext<'doc> {
949 ParseContext::new(self, node_id)
950 }
951
952 pub fn parse_tuple(&'doc self, node_id: NodeId) -> Result<TupleParser<'doc>, ParseError> {
956 TupleParser::from_doc_and_node(self, node_id)
957 }
958}
959
960impl<'doc> ParseDocument<'doc> for EureDocument {
961 type Error = ParseError;
962
963 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
964 Ok(ctx.doc().node_subtree_to_document(ctx.node_id()))
965 }
966}
967
968impl<'doc> ParseDocument<'doc> for &'doc str {
969 type Error = ParseError;
970
971 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
972 match ctx.parse_primitive()? {
973 PrimitiveValue::Text(text) => Ok(text.as_str()),
974 _ => Err(ParseError {
975 node_id: ctx.node_id(),
976 kind: ParseErrorKind::TypeMismatch {
977 expected: ValueKind::Text,
978 actual: ctx.node().content.value_kind().unwrap_or(ValueKind::Null),
979 },
980 }),
981 }
982 }
983}
984
985impl ParseDocument<'_> for String {
986 type Error = ParseError;
987
988 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
989 ctx.parse::<&str>().map(String::from)
990 }
991}
992
993impl ParseDocument<'_> for Text {
994 type Error = ParseError;
995
996 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
997 match ctx.parse_primitive()? {
998 PrimitiveValue::Text(text) => Ok(text.clone()),
999 _ => Err(ParseError {
1000 node_id: ctx.node_id(),
1001 kind: ParseErrorKind::TypeMismatch {
1002 expected: ValueKind::Text,
1003 actual: ctx.node().content.value_kind().unwrap_or(ValueKind::Null),
1004 },
1005 }),
1006 }
1007 }
1008}
1009
1010impl ParseDocument<'_> for bool {
1011 type Error = ParseError;
1012
1013 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1014 match ctx.parse_primitive()? {
1015 PrimitiveValue::Bool(b) => Ok(*b),
1016 _ => Err(ParseError {
1017 node_id: ctx.node_id(),
1018 kind: ParseErrorKind::TypeMismatch {
1019 expected: ValueKind::Bool,
1020 actual: ctx.node().content.value_kind().unwrap_or(ValueKind::Null),
1021 },
1022 }),
1023 }
1024 }
1025}
1026
1027impl ParseDocument<'_> for BigInt {
1028 type Error = ParseError;
1029
1030 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1031 match ctx.parse_primitive()? {
1032 PrimitiveValue::Integer(i) => Ok(i.clone()),
1033 _ => Err(ParseError {
1034 node_id: ctx.node_id(),
1035 kind: ParseErrorKind::TypeMismatch {
1036 expected: ValueKind::Integer,
1037 actual: ctx.node().content.value_kind().unwrap_or(ValueKind::Null),
1038 },
1039 }),
1040 }
1041 }
1042}
1043
1044impl ParseDocument<'_> for f32 {
1045 type Error = ParseError;
1046
1047 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1048 match ctx.parse_primitive()? {
1049 PrimitiveValue::F32(f) => Ok(*f),
1050 _ => Err(ParseError {
1051 node_id: ctx.node_id(),
1052 kind: ParseErrorKind::TypeMismatch {
1053 expected: ValueKind::F32,
1054 actual: ctx.node().content.value_kind().unwrap_or(ValueKind::Null),
1055 },
1056 }),
1057 }
1058 }
1059}
1060
1061impl ParseDocument<'_> for f64 {
1062 type Error = ParseError;
1063
1064 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1065 match ctx.parse_primitive()? {
1066 PrimitiveValue::F32(f) => Ok(*f as f64),
1068 PrimitiveValue::F64(f) => Ok(*f),
1069 _ => Err(ParseError {
1070 node_id: ctx.node_id(),
1071 kind: ParseErrorKind::TypeMismatch {
1072 expected: ValueKind::F64,
1073 actual: ctx.node().content.value_kind().unwrap_or(ValueKind::Null),
1074 },
1075 }),
1076 }
1077 }
1078}
1079
1080impl ParseDocument<'_> for u32 {
1081 type Error = ParseError;
1082
1083 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1084 let value: BigInt = ctx.parse()?;
1085 u32::try_from(&value).map_err(|_| ParseError {
1086 node_id: ctx.node_id(),
1087 kind: ParseErrorKind::OutOfRange(format!("value {} out of u32 range", value)),
1088 })
1089 }
1090}
1091
1092impl ParseDocument<'_> for i32 {
1093 type Error = ParseError;
1094
1095 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1096 let value: BigInt = ctx.parse()?;
1097 i32::try_from(&value).map_err(|_| ParseError {
1098 node_id: ctx.node_id(),
1099 kind: ParseErrorKind::OutOfRange(format!("value {} out of i32 range", value)),
1100 })
1101 }
1102}
1103
1104impl ParseDocument<'_> for i64 {
1105 type Error = ParseError;
1106
1107 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1108 let value: BigInt = ctx.parse()?;
1109 i64::try_from(&value).map_err(|_| ParseError {
1110 node_id: ctx.node_id(),
1111 kind: ParseErrorKind::OutOfRange(format!("value {} out of i64 range", value)),
1112 })
1113 }
1114}
1115
1116impl ParseDocument<'_> for u64 {
1117 type Error = ParseError;
1118
1119 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1120 let value: BigInt = ctx.parse()?;
1121 u64::try_from(&value).map_err(|_| ParseError {
1122 node_id: ctx.node_id(),
1123 kind: ParseErrorKind::OutOfRange(format!("value {} out of u64 range", value)),
1124 })
1125 }
1126}
1127
1128impl ParseDocument<'_> for usize {
1129 type Error = ParseError;
1130
1131 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1132 let value: BigInt = ctx.parse()?;
1133 usize::try_from(&value).map_err(|_| ParseError {
1134 node_id: ctx.node_id(),
1135 kind: ParseErrorKind::OutOfRange(format!("value {} out of usize range", value)),
1136 })
1137 }
1138}
1139
1140impl<'doc> ParseDocument<'doc> for &'doc PrimitiveValue {
1141 type Error = ParseError;
1142
1143 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1144 ctx.parse_primitive()
1145 }
1146}
1147
1148impl ParseDocument<'_> for PrimitiveValue {
1149 type Error = ParseError;
1150
1151 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1152 ctx.parse::<&PrimitiveValue>().cloned()
1153 }
1154}
1155
1156impl ParseDocument<'_> for Identifier {
1157 type Error = ParseError;
1158
1159 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1160 match ctx.parse_primitive()? {
1161 PrimitiveValue::Text(text) => text
1162 .content
1163 .parse()
1164 .map_err(ParseErrorKind::InvalidIdentifier)
1165 .map_err(|kind| ParseError {
1166 node_id: ctx.node_id(),
1167 kind,
1168 }),
1169 _ => Err(ParseError {
1170 node_id: ctx.node_id(),
1171 kind: ParseErrorKind::TypeMismatch {
1172 expected: ValueKind::Text,
1173 actual: ctx.node().content.value_kind().unwrap_or(ValueKind::Null),
1174 },
1175 }),
1176 }
1177 }
1178}
1179
1180impl<'doc> ParseDocument<'doc> for &'doc NodeArray {
1181 type Error = ParseError;
1182
1183 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1184 ctx.ensure_no_variant_path()?;
1185 match &ctx.node().content {
1186 NodeValue::Array(array) => Ok(array),
1187 value => Err(ParseError {
1188 node_id: ctx.node_id(),
1189 kind: handle_unexpected_node_value(value),
1190 }),
1191 }
1192 }
1193}
1194
1195impl<'doc, T> ParseDocument<'doc> for Vec<T>
1196where
1197 T: ParseDocument<'doc>,
1198 T::Error: From<ParseError>,
1199{
1200 type Error = T::Error;
1201
1202 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1203 ctx.ensure_no_variant_path()?;
1204 match &ctx.node().content {
1205 NodeValue::Array(array) => array
1206 .iter()
1207 .map(|item| T::parse(&ctx.at(*item)))
1208 .collect::<Result<Vec<_>, _>>(),
1209 value => Err(ParseError {
1210 node_id: ctx.node_id(),
1211 kind: handle_unexpected_node_value(value),
1212 }
1213 .into()),
1214 }
1215 }
1216}
1217
1218impl<'doc, T> ParseDocument<'doc> for IndexSet<T>
1219where
1220 T: ParseDocument<'doc> + Eq + std::hash::Hash,
1221 T::Error: From<ParseError>,
1222{
1223 type Error = T::Error;
1224 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1225 ctx.ensure_no_variant_path()?;
1226 match &ctx.node().content {
1227 NodeValue::Array(array) => array
1228 .iter()
1229 .map(|item| T::parse(&ctx.at(*item)))
1230 .collect::<Result<IndexSet<_>, _>>(),
1231 value => Err(ParseError {
1232 node_id: ctx.node_id(),
1233 kind: handle_unexpected_node_value(value),
1234 }
1235 .into()),
1236 }
1237 }
1238}
1239
1240macro_rules! parse_tuple {
1241 ($n:expr, $($var:ident),*) => {
1242 impl<'doc, $($var),*, Err> ParseDocument<'doc> for ($($var),*,)
1243 where $($var: ParseDocument<'doc, Error = Err>),*,
1244 Err: From<ParseError>,
1245 {
1246 type Error = Err;
1247
1248 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1249 ctx.ensure_no_variant_path()?;
1250 let tuple = match &ctx.node().content {
1251 NodeValue::Tuple(tuple) => tuple,
1252 value => return Err(ParseError { node_id: ctx.node_id(), kind: handle_unexpected_node_value(value) }.into()),
1253 };
1254 if tuple.len() != $n {
1255 return Err(ParseError { node_id: ctx.node_id(), kind: ParseErrorKind::UnexpectedTupleLength { expected: $n, actual: tuple.len() } }.into());
1256 }
1257 let mut iter = tuple.iter();
1258 Ok(($($var::parse(&ctx.at(*iter.next().unwrap()))?),*,))
1259 }
1260 }
1261 }
1262}
1263
1264parse_tuple!(1, A);
1265parse_tuple!(2, A, B);
1266parse_tuple!(3, A, B, C);
1267parse_tuple!(4, A, B, C, D);
1268parse_tuple!(5, A, B, C, D, E);
1269parse_tuple!(6, A, B, C, D, E, F);
1270parse_tuple!(7, A, B, C, D, E, F, G);
1271parse_tuple!(8, A, B, C, D, E, F, G, H);
1272parse_tuple!(9, A, B, C, D, E, F, G, H, I);
1273parse_tuple!(10, A, B, C, D, E, F, G, H, I, J);
1274parse_tuple!(11, A, B, C, D, E, F, G, H, I, J, K);
1275parse_tuple!(12, A, B, C, D, E, F, G, H, I, J, K, L);
1276parse_tuple!(13, A, B, C, D, E, F, G, H, I, J, K, L, M);
1277parse_tuple!(14, A, B, C, D, E, F, G, H, I, J, K, L, M, N);
1278parse_tuple!(15, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
1279parse_tuple!(16, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
1280
1281macro_rules! parse_map {
1282 ($ctx:ident) => {{
1283 $ctx.ensure_no_variant_path()?;
1284
1285 if $ctx.parser_scope() == Some(ParserScope::Extension) {
1287 let node = $ctx.node();
1289 let accessed = $ctx.flatten_ctx().map(|fc| fc.accessed_set());
1290 node.extensions
1291 .iter()
1292 .filter(|(ident, _)| {
1293 accessed.map_or(true, |a| !a.has_ext(ident))
1295 })
1296 .map(|(ident, &node_id)| {
1297 Ok((
1298 K::from_extension_ident(ident).map_err(|kind| ParseError {
1299 node_id: $ctx.node_id(),
1300 kind,
1301 })?,
1302 T::parse(&$ctx.at(node_id))?,
1303 ))
1304 })
1305 .collect::<Result<_, _>>()
1306 } else {
1307 let map = match &$ctx.node().content {
1309 NodeValue::Map(map) => map,
1310 value => {
1311 return Err(ParseError {
1312 node_id: $ctx.node_id(),
1313 kind: handle_unexpected_node_value(value),
1314 }
1315 .into());
1316 }
1317 };
1318 let accessed = $ctx
1320 .flatten_ctx()
1321 .filter(|fc| fc.scope() == ParserScope::Record)
1322 .map(|fc| fc.accessed_set().clone());
1323 map.iter()
1324 .filter(|(key, _)| {
1325 match &accessed {
1326 Some(acc) => match key {
1327 ObjectKey::String(s) => !acc.has_field(s),
1328 _ => true, },
1330 None => true, }
1332 })
1333 .map(|(key, value)| {
1334 Ok((
1335 K::from_object_key(key).map_err(|kind| ParseError {
1336 node_id: $ctx.node_id(),
1337 kind,
1338 })?,
1339 T::parse(&$ctx.at(*value))?,
1340 ))
1341 })
1342 .collect::<Result<_, _>>()
1343 }
1344 }};
1345}
1346
1347impl<'doc, K, T> ParseDocument<'doc> for Map<K, T>
1348where
1349 K: ParseObjectKey<'doc>,
1350 T: ParseDocument<'doc>,
1351 T::Error: From<ParseError>,
1352{
1353 type Error = T::Error;
1354
1355 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1356 parse_map!(ctx)
1357 }
1358}
1359
1360impl<'doc, K, T> ParseDocument<'doc> for BTreeMap<K, T>
1361where
1362 K: ParseObjectKey<'doc>,
1363 T: ParseDocument<'doc>,
1364 T::Error: From<ParseError>,
1365{
1366 type Error = T::Error;
1367 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1368 parse_map!(ctx)
1369 }
1370}
1371
1372impl<'doc, K, T> ParseDocument<'doc> for HashMap<K, T>
1373where
1374 K: ParseObjectKey<'doc>,
1375 T: ParseDocument<'doc>,
1376 T::Error: From<ParseError>,
1377{
1378 type Error = T::Error;
1379 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1380 parse_map!(ctx)
1381 }
1382}
1383
1384impl<'doc, K, T> ParseDocument<'doc> for IndexMap<K, T>
1385where
1386 K: ParseObjectKey<'doc>,
1387 T: ParseDocument<'doc>,
1388 T::Error: From<ParseError>,
1389{
1390 type Error = T::Error;
1391 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1392 parse_map!(ctx)
1393 }
1394}
1395
1396impl ParseDocument<'_> for regex::Regex {
1397 type Error = ParseError;
1398
1399 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1400 let pattern: &str = ctx.parse()?;
1401 regex::Regex::new(pattern).map_err(|e| ParseError {
1402 node_id: ctx.node_id(),
1403 kind: ParseErrorKind::InvalidPattern {
1404 kind: format!("regex '{}'", pattern),
1405 reason: e.to_string(),
1406 },
1407 })
1408 }
1409}
1410
1411impl<'doc, T> ParseDocument<'doc> for Option<T>
1418where
1419 T: ParseDocument<'doc>,
1420 T::Error: From<ParseError>,
1421{
1422 type Error = T::Error;
1423
1424 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1425 ctx.parse_union::<Option<T>, T::Error>(VariantRepr::default())?
1426 .variant("some", (T::parse).map(Some))
1427 .variant("none", |ctx: &ParseContext<'_>| {
1428 if ctx.is_null() {
1429 Ok(None)
1430 } else {
1431 Err(ParseError {
1432 node_id: ctx.node_id(),
1433 kind: ParseErrorKind::TypeMismatch {
1434 expected: ValueKind::Null,
1435 actual: ctx.node().content.value_kind().unwrap_or(ValueKind::Null),
1436 },
1437 }
1438 .into())
1439 }
1440 })
1441 .parse()
1442 }
1443}
1444
1445impl<'doc, T, E, Err> ParseDocument<'doc> for Result<T, E>
1451where
1452 T: ParseDocument<'doc, Error = Err>,
1453 E: ParseDocument<'doc, Error = Err>,
1454 Err: From<ParseError>,
1455{
1456 type Error = Err;
1457
1458 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1459 ctx.parse_union::<Self, Self::Error>(VariantRepr::default())?
1460 .variant("ok", (T::parse).map(Ok))
1461 .variant("err", (E::parse).map(Err))
1462 .parse()
1463 }
1464}
1465
1466impl ParseDocument<'_> for crate::data_model::VariantRepr {
1467 type Error = ParseError;
1468
1469 fn parse(ctx: &ParseContext<'_>) -> Result<Self, Self::Error> {
1470 use crate::data_model::VariantRepr;
1471
1472 if let Ok(value) = ctx.parse::<&str>() {
1474 return match value {
1475 "external" => Ok(VariantRepr::External),
1476 "untagged" => Ok(VariantRepr::Untagged),
1477 _ => Err(ParseError {
1478 node_id: ctx.node_id(),
1479 kind: ParseErrorKind::UnknownVariant(value.to_string()),
1480 }),
1481 };
1482 }
1483
1484 let rec = ctx.parse_record()?;
1486
1487 let tag = rec.parse_field_optional::<String>("tag")?;
1488 let content = rec.parse_field_optional::<String>("content")?;
1489
1490 rec.allow_unknown_fields()?;
1491
1492 match (tag, content) {
1493 (Some(tag), Some(content)) => Ok(VariantRepr::Adjacent { tag, content }),
1494 (Some(tag), None) => Ok(VariantRepr::Internal { tag }),
1495 (None, None) => Ok(VariantRepr::External),
1496 (None, Some(_)) => Err(ParseError {
1497 node_id: ctx.node_id(),
1498 kind: ParseErrorKind::MissingField(
1499 "tag (required when content is present)".to_string(),
1500 ),
1501 }),
1502 }
1503 }
1504}
1505
1506impl<'doc> ParseDocument<'doc> for () {
1507 type Error = ParseError;
1508 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1509 ctx.parse_tuple()?.finish()
1510 }
1511}
1512
1513impl<'doc> ParseDocument<'doc> for NodeId {
1514 type Error = ParseError;
1515 fn parse(ctx: &ParseContext<'doc>) -> Result<Self, Self::Error> {
1516 Ok(ctx.node_id())
1517 }
1518}
1519
1520pub trait DocumentParser<'doc> {
1521 type Output;
1522 type Error;
1523 fn parse(&mut self, ctx: &ParseContext<'doc>) -> Result<Self::Output, Self::Error>;
1524}
1525
1526pub struct AlwaysParser<T, E>(T, PhantomData<E>);
1527
1528impl<T, E> AlwaysParser<T, E> {
1529 pub fn new(value: T) -> AlwaysParser<T, E> {
1530 Self(value, PhantomData)
1531 }
1532}
1533
1534impl<'doc, T, E> DocumentParser<'doc> for AlwaysParser<T, E>
1535where
1536 T: Clone,
1537{
1538 type Output = T;
1539 type Error = E;
1540 fn parse(&mut self, _ctx: &ParseContext<'doc>) -> Result<Self::Output, Self::Error> {
1541 Ok(self.0.clone())
1542 }
1543}
1544
1545impl<'doc, T, F, E> DocumentParser<'doc> for F
1546where
1547 F: FnMut(&ParseContext<'doc>) -> Result<T, E>,
1548{
1549 type Output = T;
1550 type Error = E;
1551 fn parse(&mut self, ctx: &ParseContext<'doc>) -> Result<Self::Output, Self::Error> {
1552 (*self)(ctx)
1553 }
1554}
1555
1556pub struct LiteralParser<T>(pub T);
1557
1558impl<'doc, T, E> DocumentParser<'doc> for LiteralParser<T>
1559where
1560 T: ParseDocument<'doc, Error = E> + PartialEq + core::fmt::Debug,
1561 E: From<ParseError>,
1562{
1563 type Output = T;
1564 type Error = E;
1565 fn parse(&mut self, ctx: &ParseContext<'doc>) -> Result<Self::Output, Self::Error> {
1566 let value: T = ctx.parse::<T>()?;
1567 if value == self.0 {
1568 Ok(value)
1569 } else {
1570 Err(ParseError {
1571 node_id: ctx.node_id(),
1572 kind: ParseErrorKind::LiteralMismatch {
1573 expected: format!("{:?}", self.0),
1574 actual: format!("{:?}", value),
1575 },
1576 }
1577 .into())
1578 }
1579 }
1580}
1581
1582pub struct VariantLiteralParser(pub &'static str);
1588
1589impl<'doc> DocumentParser<'doc> for VariantLiteralParser {
1590 type Output = &'static str;
1591 type Error = ParseError;
1592 fn parse(&mut self, ctx: &ParseContext<'doc>) -> Result<Self::Output, Self::Error> {
1593 let value: &str = ctx.parse()?;
1594 if value == self.0 {
1595 Ok(self.0)
1596 } else {
1597 Err(ParseError {
1598 node_id: ctx.node_id(),
1599 kind: ParseErrorKind::UnknownVariant(value.to_string()),
1600 })
1601 }
1602 }
1603}
1604
1605pub struct MapParser<T, F> {
1606 parser: T,
1607 mapper: F,
1608}
1609
1610impl<'doc, T, O, F> DocumentParser<'doc> for MapParser<T, F>
1611where
1612 T: DocumentParser<'doc>,
1613 F: FnMut(T::Output) -> O,
1614{
1615 type Output = O;
1616 type Error = T::Error;
1617 fn parse(&mut self, ctx: &ParseContext<'doc>) -> Result<Self::Output, Self::Error> {
1618 self.parser.parse(ctx).map(|value| (self.mapper)(value))
1619 }
1620}
1621
1622pub struct AndThenParser<T, F> {
1623 parser: T,
1624 mapper: F,
1625}
1626
1627impl<'doc, T, O, F, E> DocumentParser<'doc> for AndThenParser<T, F>
1628where
1629 T: DocumentParser<'doc, Error = E>,
1630 F: Fn(T::Output) -> Result<O, E>,
1631{
1632 type Output = O;
1633 type Error = E;
1634 fn parse(&mut self, ctx: &ParseContext<'doc>) -> Result<Self::Output, Self::Error> {
1635 let value = self.parser.parse(ctx)?;
1636 (self.mapper)(value)
1637 }
1638}
1639
1640pub trait DocumentParserExt<'doc>: DocumentParser<'doc> + Sized {
1641 fn map<O, F>(self, mapper: F) -> MapParser<Self, F>
1642 where
1643 F: Fn(Self::Output) -> O,
1644 {
1645 MapParser {
1646 parser: self,
1647 mapper,
1648 }
1649 }
1650
1651 fn and_then<O, F>(self, mapper: F) -> AndThenParser<Self, F>
1652 where
1653 F: Fn(Self::Output) -> Result<O, Self::Error>,
1654 {
1655 AndThenParser {
1656 parser: self,
1657 mapper,
1658 }
1659 }
1660}
1661
1662impl<'doc, T> DocumentParserExt<'doc> for T where T: DocumentParser<'doc> {}
1663
1664#[cfg(test)]
1665mod tests {
1666 use super::*;
1667 use crate::document::node::NodeValue;
1668 use crate::eure;
1669 use crate::identifier::Identifier;
1670 use crate::text::Text;
1671 use crate::value::ObjectKey;
1672 use num_bigint::BigInt;
1673
1674 fn identifier(s: &str) -> Identifier {
1675 s.parse().unwrap()
1676 }
1677
1678 fn create_record_with_variant(
1680 field_name: &str,
1681 value: NodeValue,
1682 variant: &str,
1683 ) -> EureDocument {
1684 let mut doc = EureDocument::new();
1685 let root_id = doc.get_root_id();
1686
1687 let field_id = doc
1689 .add_map_child(ObjectKey::String(field_name.to_string()), root_id)
1690 .unwrap()
1691 .node_id;
1692 doc.node_mut(field_id).content = value;
1693
1694 let variant_node_id = doc
1696 .add_extension(identifier("variant"), field_id)
1697 .unwrap()
1698 .node_id;
1699 doc.node_mut(variant_node_id).content =
1700 NodeValue::Primitive(PrimitiveValue::Text(Text::plaintext(variant.to_string())));
1701
1702 doc
1703 }
1704
1705 #[test]
1706 fn test_option_some_tagged() {
1707 let doc = create_record_with_variant(
1708 "value",
1709 NodeValue::Primitive(PrimitiveValue::Integer(BigInt::from(42))),
1710 "some",
1711 );
1712 let root_id = doc.get_root_id();
1713 let rec = doc.parse_record(root_id).unwrap();
1714 let value: Option<i32> = rec.parse_field("value").unwrap();
1715 assert_eq!(value, Some(42));
1716 }
1717
1718 #[test]
1719 fn test_option_none_tagged() {
1720 let doc =
1721 create_record_with_variant("value", NodeValue::Primitive(PrimitiveValue::Null), "none");
1722 let root_id = doc.get_root_id();
1723 let rec = doc.parse_record(root_id).unwrap();
1724 let value: Option<i32> = rec.parse_field("value").unwrap();
1725 assert_eq!(value, None);
1726 }
1727
1728 #[test]
1729 fn test_option_some_untagged() {
1730 let doc = eure!({ value = 42 });
1732 let root_id = doc.get_root_id();
1733 let rec = doc.parse_record(root_id).unwrap();
1734 let value: Option<i32> = rec.parse_field("value").unwrap();
1735 assert_eq!(value, Some(42));
1736 }
1737
1738 #[test]
1739 fn test_option_none_untagged() {
1740 let doc = eure!({ value = null });
1742 let root_id = doc.get_root_id();
1743 let rec = doc.parse_record(root_id).unwrap();
1744 let value: Option<i32> = rec.parse_field("value").unwrap();
1745 assert_eq!(value, None);
1746 }
1747
1748 #[test]
1749 fn test_result_ok_tagged() {
1750 let doc = create_record_with_variant(
1751 "value",
1752 NodeValue::Primitive(PrimitiveValue::Integer(BigInt::from(42))),
1753 "ok",
1754 );
1755 let root_id = doc.get_root_id();
1756 let rec = doc.parse_record(root_id).unwrap();
1757 let value: Result<i32, String> = rec.parse_field("value").unwrap();
1758 assert_eq!(value, Ok(42));
1759 }
1760
1761 #[test]
1762 fn test_result_err_tagged() {
1763 let doc = create_record_with_variant(
1764 "value",
1765 NodeValue::Primitive(PrimitiveValue::Text(Text::plaintext(
1766 "error message".to_string(),
1767 ))),
1768 "err",
1769 );
1770 let root_id = doc.get_root_id();
1771 let rec = doc.parse_record(root_id).unwrap();
1772 let value: Result<i32, String> = rec.parse_field("value").unwrap();
1773 assert_eq!(value, Err("error message".to_string()));
1774 }
1775
1776 #[test]
1777 fn test_nested_result_option_ok_some() {
1778 let doc = create_record_with_variant(
1780 "value",
1781 NodeValue::Primitive(PrimitiveValue::Integer(BigInt::from(42))),
1782 "ok.some",
1783 );
1784 let root_id = doc.get_root_id();
1785 let rec = doc.parse_record(root_id).unwrap();
1786 let value: Result<Option<i32>, String> = rec.parse_field("value").unwrap();
1787 assert_eq!(value, Ok(Some(42)));
1788 }
1789
1790 #[test]
1791 fn test_nested_result_option_ok_none() {
1792 let doc = create_record_with_variant(
1794 "value",
1795 NodeValue::Primitive(PrimitiveValue::Null),
1796 "ok.none",
1797 );
1798 let root_id = doc.get_root_id();
1799 let rec = doc.parse_record(root_id).unwrap();
1800 let value: Result<Option<i32>, String> = rec.parse_field("value").unwrap();
1801 assert_eq!(value, Ok(None));
1802 }
1803
1804 #[test]
1805 fn test_nested_result_option_err() {
1806 let doc = create_record_with_variant(
1808 "value",
1809 NodeValue::Primitive(PrimitiveValue::Text(Text::plaintext("error".to_string()))),
1810 "err",
1811 );
1812 let root_id = doc.get_root_id();
1813 let rec = doc.parse_record(root_id).unwrap();
1814 let value: Result<Option<i32>, String> = rec.parse_field("value").unwrap();
1815 assert_eq!(value, Err("error".to_string()));
1816 }
1817
1818 #[test]
1819 fn test_deeply_nested_option_option() {
1820 let doc = create_record_with_variant(
1822 "value",
1823 NodeValue::Primitive(PrimitiveValue::Integer(BigInt::from(42))),
1824 "some.some",
1825 );
1826 let root_id = doc.get_root_id();
1827 let rec = doc.parse_record(root_id).unwrap();
1828 let value: Option<Option<i32>> = rec.parse_field("value").unwrap();
1829 assert_eq!(value, Some(Some(42)));
1830 }
1831
1832 #[test]
1833 fn test_deeply_nested_option_none() {
1834 let doc = create_record_with_variant(
1836 "value",
1837 NodeValue::Primitive(PrimitiveValue::Null),
1838 "some.none",
1839 );
1840 let root_id = doc.get_root_id();
1841 let rec = doc.parse_record(root_id).unwrap();
1842 let value: Option<Option<i32>> = rec.parse_field("value").unwrap();
1843 assert_eq!(value, Some(None));
1844 }
1845
1846 #[test]
1847 fn test_outer_none() {
1848 let doc =
1850 create_record_with_variant("value", NodeValue::Primitive(PrimitiveValue::Null), "none");
1851 let root_id = doc.get_root_id();
1852 let rec = doc.parse_record(root_id).unwrap();
1853 let value: Option<Option<i32>> = rec.parse_field("value").unwrap();
1854 assert_eq!(value, None);
1855 }
1856}