1extern crate alloc;
36
37use alloc::{
38 borrow::Cow,
39 collections::VecDeque,
40 string::{String, ToString},
41 vec::Vec,
42};
43
44use facet_format::{
45 ContainerKind, FieldEvidence, FieldKey, FieldLocationHint, FormatParser, ParseEvent,
46 ProbeStream, ScalarValue,
47};
48use toml_parser::{
49 ErrorSink, Raw, Source,
50 decoder::ScalarKind,
51 parser::{Event, EventKind, RecursionGuard, parse_document},
52};
53
54use crate::{TomlError, TomlErrorKind};
55
56struct ParseErrorCollector {
62 error: Option<String>,
63}
64
65impl ParseErrorCollector {
66 const fn new() -> Self {
67 Self { error: None }
68 }
69
70 const fn take_error(&mut self) -> Option<String> {
71 self.error.take()
72 }
73}
74
75impl ErrorSink for ParseErrorCollector {
76 fn report_error(&mut self, error: toml_parser::ParseError) {
77 if self.error.is_none() {
78 self.error = Some(error.description().to_string());
79 }
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89enum SegmentKind {
90 Table,
92 Array,
94 ArrayElement,
96}
97
98#[derive(Debug, Clone)]
100struct PathSegment<'de> {
101 name: Cow<'de, str>,
102 kind: SegmentKind,
103}
104
105pub struct TomlParser<'de> {
114 input: &'de str,
116 events: Vec<Event>,
118 pos: usize,
120 current_path: Vec<PathSegment<'de>>,
122 pending_events: VecDeque<ParseEvent<'de>>,
124 event_peek: Option<ParseEvent<'de>>,
126 root_started: bool,
128 root_ended: bool,
130 inline_stack: Vec<(bool, usize)>,
135 last_scalar_span: Option<facet_reflect::Span>,
137}
138
139impl<'de> TomlParser<'de> {
140 pub fn new(input: &'de str) -> Result<Self, TomlError> {
142 let source = Source::new(input);
143 let tokens: Vec<_> = source.lex().collect();
144 let mut events: Vec<Event> = Vec::new();
145 let mut guarded = RecursionGuard::new(&mut events, 128);
146 let mut error_collector = ParseErrorCollector::new();
147
148 parse_document(&tokens, &mut guarded, &mut error_collector);
149
150 if let Some(err_msg) = error_collector.take_error() {
151 return Err(TomlError::without_span(TomlErrorKind::Parse(err_msg)));
152 }
153
154 Ok(Self {
155 input,
156 events,
157 pos: 0,
158 current_path: Vec::new(),
159 pending_events: VecDeque::new(),
160 event_peek: None,
161 root_started: false,
162 root_ended: false,
163 inline_stack: Vec::new(),
164 last_scalar_span: None,
165 })
166 }
167
168 pub const fn input(&self) -> &'de str {
170 self.input
171 }
172
173 #[inline]
175 fn should_skip(event: &Event) -> bool {
176 matches!(
177 event.kind(),
178 EventKind::Whitespace | EventKind::Comment | EventKind::Newline
179 )
180 }
181
182 fn peek_raw(&self) -> Option<&Event> {
184 let mut pos = self.pos;
185 while pos < self.events.len() {
186 let event = &self.events[pos];
187 if !Self::should_skip(event) {
188 return Some(event);
189 }
190 pos += 1;
191 }
192 None
193 }
194
195 fn next_raw(&mut self) -> Option<&Event> {
197 while self.pos < self.events.len() {
198 let event = &self.events[self.pos];
199 self.pos += 1;
200 if !Self::should_skip(event) {
201 return Some(event);
202 }
203 }
204 None
205 }
206
207 fn get_span_str(&self, event: &Event) -> &'de str {
209 let span = event.span();
210 &self.input[span.start()..span.end()]
211 }
212
213 fn raw_from_event(&self, event: &Event) -> Raw<'de> {
215 let span = event.span();
216 Raw::new_unchecked(
217 &self.input[span.start()..span.end()],
218 event.encoding(),
219 span,
220 )
221 }
222
223 fn decode_scalar(&self, event: &Event) -> Result<ScalarValue<'de>, TomlError> {
225 let raw = self.raw_from_event(event);
226 let mut output: Cow<'de, str> = Cow::Borrowed("");
227 let kind = raw.decode_scalar(&mut output, &mut ());
228
229 match kind {
230 ScalarKind::String => {
231 Ok(ScalarValue::Str(output))
233 }
234 ScalarKind::Boolean(b) => Ok(ScalarValue::Bool(b)),
235 ScalarKind::Integer(radix) => {
236 let clean: String = output.chars().filter(|c| *c != '_').collect();
238 let n: i64 = i64::from_str_radix(&clean, radix.value()).map_err(|e| {
239 TomlError::without_span(TomlErrorKind::InvalidValue {
240 message: e.to_string(),
241 })
242 })?;
243 Ok(ScalarValue::I64(n))
244 }
245 ScalarKind::Float => {
246 let clean: String = output.chars().filter(|c| *c != '_').collect();
247 let f: f64 = match clean.as_str() {
249 "inf" | "+inf" => f64::INFINITY,
250 "-inf" => f64::NEG_INFINITY,
251 "nan" | "+nan" | "-nan" => f64::NAN,
252 _ => clean.parse().map_err(|e: core::num::ParseFloatError| {
253 TomlError::without_span(TomlErrorKind::InvalidValue {
254 message: e.to_string(),
255 })
256 })?,
257 };
258 Ok(ScalarValue::F64(f))
259 }
260 ScalarKind::DateTime => {
261 Ok(ScalarValue::Str(output))
263 }
264 }
265 }
266
267 fn parse_dotted_key(&mut self) -> Vec<Cow<'de, str>> {
270 let mut parts = Vec::new();
271
272 loop {
273 let Some(event) = self.peek_raw() else {
274 break;
275 };
276
277 match event.kind() {
278 EventKind::SimpleKey => {
279 let key = self.decode_key(event);
280 self.next_raw(); parts.push(key);
282 }
283 EventKind::KeySep => {
284 self.next_raw();
286 }
287 _ => break,
288 }
289 }
290
291 parts
292 }
293
294 fn decode_key(&self, event: &Event) -> Cow<'de, str> {
296 let raw = self.raw_from_event(event);
297 let mut output: Cow<'de, str> = Cow::Borrowed("");
298 raw.decode_key(&mut output, &mut ());
299 output
300 }
301
302 const fn end_event_for_segment(segment: &PathSegment<'_>) -> ParseEvent<'static> {
304 match segment.kind {
305 SegmentKind::Table => ParseEvent::StructEnd,
306 SegmentKind::Array => ParseEvent::SequenceEnd,
307 SegmentKind::ArrayElement => ParseEvent::StructEnd,
308 }
309 }
310
311 fn compute_navigation_to_table(
326 &self,
327 target_names: &[Cow<'de, str>],
328 ) -> (Vec<ParseEvent<'de>>, Vec<PathSegment<'de>>) {
329 let mut events = Vec::new();
330
331 let mut current_idx = 0;
334 let mut target_idx = 0;
335
336 while current_idx < self.current_path.len() && target_idx < target_names.len() {
337 let seg = &self.current_path[current_idx];
338 let target_name = &target_names[target_idx];
339
340 if seg.name != *target_name {
341 break;
342 }
343
344 current_idx += 1;
345
346 if matches!(seg.kind, SegmentKind::Array) && current_idx < self.current_path.len() {
349 let next_seg = &self.current_path[current_idx];
350 if matches!(next_seg.kind, SegmentKind::ArrayElement) && next_seg.name == seg.name {
351 current_idx += 1;
352 }
353 }
354
355 target_idx += 1;
356 }
357
358 for segment in self.current_path[current_idx..].iter().rev() {
360 events.push(Self::end_event_for_segment(segment));
361 }
362
363 let mut new_path: Vec<PathSegment<'de>> = self.current_path[..current_idx].to_vec();
365 for name in &target_names[target_idx..] {
366 events.push(ParseEvent::FieldKey(FieldKey::new(
367 name.clone(),
368 FieldLocationHint::KeyValue,
369 )));
370 events.push(ParseEvent::StructStart(ContainerKind::Object));
371 new_path.push(PathSegment {
372 name: name.clone(),
373 kind: SegmentKind::Table,
374 });
375 }
376
377 (events, new_path)
378 }
379
380 fn compute_navigation_to_array_table(
394 &self,
395 target_names: &[Cow<'de, str>],
396 ) -> (Vec<ParseEvent<'de>>, Vec<PathSegment<'de>>) {
397 let mut events = Vec::new();
398
399 let mut current_idx = 0;
401 let mut target_idx = 0;
402
403 while current_idx < self.current_path.len() && target_idx < target_names.len() {
404 let seg = &self.current_path[current_idx];
405 let target_name = &target_names[target_idx];
406
407 if seg.name != *target_name {
408 break;
409 }
410
411 if matches!(seg.kind, SegmentKind::Array) {
413 let more_targets_after = target_idx + 1 < target_names.len();
416
417 if more_targets_after {
418 current_idx += 1;
420 if current_idx < self.current_path.len() {
422 let next_seg = &self.current_path[current_idx];
423 if matches!(next_seg.kind, SegmentKind::ArrayElement)
424 && next_seg.name == seg.name
425 {
426 current_idx += 1;
427 }
428 }
429 target_idx += 1;
430 } else {
431 break;
434 }
435 } else if matches!(seg.kind, SegmentKind::ArrayElement) {
436 break;
438 } else {
439 current_idx += 1;
441 target_idx += 1;
442 }
443 }
444
445 for segment in self.current_path[current_idx..].iter().rev() {
447 events.push(Self::end_event_for_segment(segment));
448 }
449
450 let mut new_path: Vec<PathSegment<'de>> = self.current_path[..current_idx].to_vec();
452
453 if target_names.len() > target_idx {
454 for name in &target_names[target_idx..target_names.len() - 1] {
456 events.push(ParseEvent::FieldKey(FieldKey::new(
457 name.clone(),
458 FieldLocationHint::KeyValue,
459 )));
460 events.push(ParseEvent::StructStart(ContainerKind::Object));
461 new_path.push(PathSegment {
462 name: name.clone(),
463 kind: SegmentKind::Table,
464 });
465 }
466
467 let array_name = target_names.last().unwrap();
469 events.push(ParseEvent::FieldKey(FieldKey::new(
470 array_name.clone(),
471 FieldLocationHint::KeyValue,
472 )));
473 events.push(ParseEvent::SequenceStart(ContainerKind::Array));
474 events.push(ParseEvent::StructStart(ContainerKind::Object));
475
476 new_path.push(PathSegment {
477 name: array_name.clone(),
478 kind: SegmentKind::Array,
479 });
480 new_path.push(PathSegment {
481 name: array_name.clone(),
482 kind: SegmentKind::ArrayElement,
483 });
484 }
485
486 (events, new_path)
487 }
488
489 fn produce_event(&mut self) -> Result<Option<ParseEvent<'de>>, TomlError> {
491 if let Some(event) = self.pending_events.pop_front() {
493 return Ok(Some(event));
494 }
495
496 if !self.inline_stack.is_empty() {
498 return self.produce_inline_event();
499 }
500
501 if !self.root_started {
503 self.root_started = true;
504 return Ok(Some(ParseEvent::StructStart(ContainerKind::Object)));
505 }
506
507 let Some(event) = self.peek_raw() else {
509 if self.root_ended {
511 return Ok(None);
512 }
513
514 for segment in self.current_path.iter().rev() {
516 self.pending_events
517 .push_back(Self::end_event_for_segment(segment));
518 }
519 self.current_path.clear();
520
521 self.pending_events.push_back(ParseEvent::StructEnd);
523 self.root_ended = true;
524
525 return Ok(self.pending_events.pop_front());
526 };
527
528 match event.kind() {
529 EventKind::StdTableOpen => {
530 self.next_raw(); let path = self.parse_dotted_key();
533
534 if let Some(close) = self.peek_raw()
536 && matches!(close.kind(), EventKind::StdTableClose)
537 {
538 self.next_raw();
539 }
540
541 let (nav_events, new_path) = self.compute_navigation_to_table(&path);
543 for e in nav_events {
544 self.pending_events.push_back(e);
545 }
546 self.current_path = new_path;
547
548 if self.pending_events.is_empty() {
550 return self.produce_event();
551 }
552
553 Ok(self.pending_events.pop_front())
554 }
555
556 EventKind::ArrayTableOpen => {
557 self.next_raw(); let path = self.parse_dotted_key();
560
561 if let Some(close) = self.peek_raw()
563 && matches!(close.kind(), EventKind::ArrayTableClose)
564 {
565 self.next_raw();
566 }
567
568 let (nav_events, new_path) = self.compute_navigation_to_array_table(&path);
570 for e in nav_events {
571 self.pending_events.push_back(e);
572 }
573 self.current_path = new_path;
574
575 Ok(self.pending_events.pop_front())
576 }
577
578 EventKind::SimpleKey => {
579 let key_parts = self.parse_dotted_key();
581
582 if let Some(sep) = self.peek_raw()
584 && matches!(sep.kind(), EventKind::KeyValSep)
585 {
586 self.next_raw();
587 }
588
589 if key_parts.len() > 1 {
592 for name in &key_parts[..key_parts.len() - 1] {
594 self.pending_events
595 .push_back(ParseEvent::FieldKey(FieldKey::new(
596 name.clone(),
597 FieldLocationHint::KeyValue,
598 )));
599 self.pending_events
600 .push_back(ParseEvent::StructStart(ContainerKind::Object));
601 }
602
603 let final_key = key_parts.last().unwrap();
605 self.pending_events
606 .push_back(ParseEvent::FieldKey(FieldKey::new(
607 final_key.clone(),
608 FieldLocationHint::KeyValue,
609 )));
610
611 let inline_depth_before = self.inline_stack.len();
613
614 self.parse_value_into_pending()?;
616
617 let entered_inline_container = self.inline_stack.len() > inline_depth_before;
619
620 if entered_inline_container {
621 let num_deferred = key_parts.len() - 1;
623 if let Some((_, deferred_closes)) = self.inline_stack.last_mut() {
624 *deferred_closes += num_deferred;
625 }
626 } else {
627 for _ in 0..key_parts.len() - 1 {
629 self.pending_events.push_back(ParseEvent::StructEnd);
630 }
631 }
632
633 Ok(self.pending_events.pop_front())
634 } else {
635 let key = key_parts.into_iter().next().unwrap();
637 self.pending_events
638 .push_back(ParseEvent::FieldKey(FieldKey::new(
639 key,
640 FieldLocationHint::KeyValue,
641 )));
642
643 self.parse_value_into_pending()?;
645
646 Ok(self.pending_events.pop_front())
647 }
648 }
649
650 EventKind::Error => {
651 let span_str = self.get_span_str(event);
652 Err(TomlError::without_span(TomlErrorKind::Parse(
653 span_str.to_string(),
654 )))
655 }
656
657 _ => {
658 self.next_raw();
660 self.produce_event()
661 }
662 }
663 }
664
665 fn parse_value_into_pending(&mut self) -> Result<(), TomlError> {
667 let Some(event) = self.peek_raw() else {
668 return Err(TomlError::without_span(TomlErrorKind::UnexpectedEof {
669 expected: "value",
670 }));
671 };
672
673 match event.kind() {
674 EventKind::Scalar => {
675 let scalar = self.decode_scalar(event)?;
676 let span = event.span();
678 self.last_scalar_span = Some(facet_reflect::Span::new(
679 span.start(),
680 span.end() - span.start(),
681 ));
682 self.next_raw();
683 self.pending_events.push_back(ParseEvent::Scalar(scalar));
684 }
685
686 EventKind::InlineTableOpen => {
687 self.next_raw();
688 self.pending_events
689 .push_back(ParseEvent::StructStart(ContainerKind::Object));
690 self.inline_stack.push((true, 0)); }
692
693 EventKind::ArrayOpen => {
694 self.next_raw();
695 self.pending_events
696 .push_back(ParseEvent::SequenceStart(ContainerKind::Array));
697 self.inline_stack.push((false, 0)); }
699
700 _ => {
701 return Err(TomlError::without_span(TomlErrorKind::UnexpectedType {
702 expected: "value",
703 got: "unexpected token",
704 }));
705 }
706 }
707
708 Ok(())
709 }
710
711 fn produce_inline_event(&mut self) -> Result<Option<ParseEvent<'de>>, TomlError> {
713 if let Some(event) = self.pending_events.pop_front() {
715 return Ok(Some(event));
716 }
717
718 let (is_inline_table, _deferred_closes) = *self.inline_stack.last().unwrap();
719
720 let Some(event) = self.peek_raw() else {
721 return Err(TomlError::without_span(TomlErrorKind::UnexpectedEof {
722 expected: if is_inline_table { "}" } else { "]" },
723 }));
724 };
725
726 match event.kind() {
727 EventKind::InlineTableClose if is_inline_table => {
728 self.next_raw();
729 let (_, deferred_closes) = self.inline_stack.pop().unwrap();
730 self.pending_events.push_back(ParseEvent::StructEnd);
732 for _ in 0..deferred_closes {
734 self.pending_events.push_back(ParseEvent::StructEnd);
735 }
736 Ok(self.pending_events.pop_front())
737 }
738
739 EventKind::ArrayClose if !is_inline_table => {
740 self.next_raw();
741 let (_, deferred_closes) = self.inline_stack.pop().unwrap();
742 self.pending_events.push_back(ParseEvent::SequenceEnd);
744 for _ in 0..deferred_closes {
746 self.pending_events.push_back(ParseEvent::StructEnd);
747 }
748 Ok(self.pending_events.pop_front())
749 }
750
751 EventKind::ValueSep => {
752 self.next_raw();
754 self.produce_inline_event()
755 }
756
757 EventKind::SimpleKey if is_inline_table => {
758 let key_parts = self.parse_dotted_key();
760
761 if let Some(sep) = self.peek_raw()
763 && matches!(sep.kind(), EventKind::KeyValSep)
764 {
765 self.next_raw();
766 }
767
768 if key_parts.len() > 1 {
770 for name in &key_parts[..key_parts.len() - 1] {
771 self.pending_events
772 .push_back(ParseEvent::FieldKey(FieldKey::new(
773 name.clone(),
774 FieldLocationHint::KeyValue,
775 )));
776 self.pending_events
777 .push_back(ParseEvent::StructStart(ContainerKind::Object));
778 }
779
780 let final_key = key_parts.last().unwrap();
781 self.pending_events
782 .push_back(ParseEvent::FieldKey(FieldKey::new(
783 final_key.clone(),
784 FieldLocationHint::KeyValue,
785 )));
786
787 let inline_depth_before = self.inline_stack.len();
789
790 self.parse_value_into_pending()?;
791
792 let entered_inline_container = self.inline_stack.len() > inline_depth_before;
794
795 if entered_inline_container {
796 let num_deferred = key_parts.len() - 1;
798 if let Some((_, deferred_closes)) = self.inline_stack.last_mut() {
799 *deferred_closes += num_deferred;
800 }
801 } else {
802 for _ in 0..key_parts.len() - 1 {
804 self.pending_events.push_back(ParseEvent::StructEnd);
805 }
806 }
807
808 Ok(self.pending_events.pop_front())
809 } else {
810 let key = key_parts.into_iter().next().unwrap();
811 self.pending_events
812 .push_back(ParseEvent::FieldKey(FieldKey::new(
813 key,
814 FieldLocationHint::KeyValue,
815 )));
816 self.parse_value_into_pending()?;
817 Ok(self.pending_events.pop_front())
818 }
819 }
820
821 EventKind::Scalar if !is_inline_table => {
822 let scalar = self.decode_scalar(event)?;
824 let span = event.span();
826 self.last_scalar_span = Some(facet_reflect::Span::new(
827 span.start(),
828 span.end() - span.start(),
829 ));
830 self.next_raw();
831 Ok(Some(ParseEvent::Scalar(scalar)))
832 }
833
834 EventKind::InlineTableOpen if !is_inline_table => {
835 self.next_raw();
837 self.inline_stack.push((true, 0));
838 Ok(Some(ParseEvent::StructStart(ContainerKind::Object)))
839 }
840
841 EventKind::ArrayOpen if !is_inline_table => {
842 self.next_raw();
844 self.inline_stack.push((false, 0));
845 Ok(Some(ParseEvent::SequenceStart(ContainerKind::Array)))
846 }
847
848 _ => {
849 self.next_raw();
851 self.produce_inline_event()
852 }
853 }
854 }
855
856 fn skip_current_value(&mut self) -> Result<(), TomlError> {
864 let Some(event) = self.produce_event()? else {
866 return Ok(());
867 };
868
869 match event {
870 ParseEvent::Scalar(_) => {
871 Ok(())
873 }
874 ParseEvent::StructStart(_) => {
875 let mut depth = 1;
877 while depth > 0 {
878 let Some(event) = self.produce_event()? else {
879 return Err(TomlError::without_span(TomlErrorKind::UnexpectedEof {
880 expected: "struct end",
881 }));
882 };
883 match event {
884 ParseEvent::StructStart(_) => depth += 1,
885 ParseEvent::StructEnd => depth -= 1,
886 _ => {}
887 }
888 }
889 Ok(())
890 }
891 ParseEvent::SequenceStart(_) => {
892 let mut depth = 1;
894 while depth > 0 {
895 let Some(event) = self.produce_event()? else {
896 return Err(TomlError::without_span(TomlErrorKind::UnexpectedEof {
897 expected: "sequence end",
898 }));
899 };
900 match event {
901 ParseEvent::SequenceStart(_) => depth += 1,
902 ParseEvent::SequenceEnd => depth -= 1,
903 _ => {}
904 }
905 }
906 Ok(())
907 }
908 _ => {
909 Ok(())
911 }
912 }
913 }
914
915 fn build_probe(&self) -> Result<Vec<FieldEvidence<'de>>, TomlError> {
917 let mut evidence = Vec::new();
918 let mut pos = self.pos;
919
920 while pos < self.events.len() {
922 let event = &self.events[pos];
923
924 if Self::should_skip(event) {
925 pos += 1;
926 continue;
927 }
928
929 match event.kind() {
930 EventKind::SimpleKey => {
931 let key = self.decode_key(event);
932 pos += 1;
933
934 while pos < self.events.len() {
936 let e = &self.events[pos];
937 if !Self::should_skip(e) {
938 break;
939 }
940 pos += 1;
941 }
942
943 while pos < self.events.len() {
945 let e = &self.events[pos];
946 if Self::should_skip(e) {
947 pos += 1;
948 continue;
949 }
950 if matches!(e.kind(), EventKind::KeySep | EventKind::SimpleKey) {
951 pos += 1;
952 continue;
953 }
954 break;
955 }
956
957 if pos < self.events.len() {
959 let e = &self.events[pos];
960 if matches!(e.kind(), EventKind::KeyValSep) {
961 pos += 1;
962 }
963 }
964
965 while pos < self.events.len() {
967 let e = &self.events[pos];
968 if !Self::should_skip(e) {
969 break;
970 }
971 pos += 1;
972 }
973
974 let scalar_value = if pos < self.events.len() {
976 let e = &self.events[pos];
977 if matches!(e.kind(), EventKind::Scalar) {
978 self.decode_scalar(e).ok()
979 } else {
980 None
981 }
982 } else {
983 None
984 };
985
986 if let Some(sv) = scalar_value {
987 evidence.push(FieldEvidence::with_scalar_value(
988 key,
989 FieldLocationHint::KeyValue,
990 None,
991 sv,
992 ));
993 } else {
994 evidence.push(FieldEvidence::new(key, FieldLocationHint::KeyValue, None));
995 }
996 }
997
998 EventKind::StdTableOpen
999 | EventKind::ArrayTableOpen
1000 | EventKind::InlineTableClose
1001 | EventKind::ArrayClose => {
1002 break;
1004 }
1005
1006 _ => {
1007 pos += 1;
1008 }
1009 }
1010 }
1011
1012 Ok(evidence)
1013 }
1014}
1015
1016impl<'de> FormatParser<'de> for TomlParser<'de> {
1017 type Error = TomlError;
1018 type Probe<'a>
1019 = TomlProbe<'de>
1020 where
1021 Self: 'a;
1022
1023 fn next_event(&mut self) -> Result<Option<ParseEvent<'de>>, Self::Error> {
1024 if let Some(event) = self.event_peek.take() {
1025 return Ok(Some(event));
1026 }
1027 self.produce_event()
1028 }
1029
1030 fn peek_event(&mut self) -> Result<Option<ParseEvent<'de>>, Self::Error> {
1031 if let Some(event) = self.event_peek.clone() {
1032 return Ok(Some(event));
1033 }
1034 let event = self.produce_event()?;
1035 if let Some(ref e) = event {
1036 self.event_peek = Some(e.clone());
1037 }
1038 Ok(event)
1039 }
1040
1041 fn skip_value(&mut self) -> Result<(), Self::Error> {
1042 debug_assert!(
1043 self.event_peek.is_none(),
1044 "skip_value called while an event is buffered"
1045 );
1046 self.skip_current_value()
1047 }
1048
1049 fn begin_probe(&mut self) -> Result<Self::Probe<'_>, Self::Error> {
1050 let evidence = self.build_probe()?;
1051 Ok(TomlProbe { evidence, idx: 0 })
1052 }
1053
1054 fn capture_raw(&mut self) -> Result<Option<&'de str>, Self::Error> {
1055 self.skip_value()?;
1057 Ok(None)
1058 }
1059
1060 fn current_span(&self) -> Option<facet_reflect::Span> {
1061 self.last_scalar_span
1062 }
1063}
1064
1065pub struct TomlProbe<'de> {
1067 evidence: Vec<FieldEvidence<'de>>,
1068 idx: usize,
1069}
1070
1071impl<'de> ProbeStream<'de> for TomlProbe<'de> {
1072 type Error = TomlError;
1073
1074 fn next(&mut self) -> Result<Option<FieldEvidence<'de>>, Self::Error> {
1075 if self.idx >= self.evidence.len() {
1076 Ok(None)
1077 } else {
1078 let ev = self.evidence[self.idx].clone();
1079 self.idx += 1;
1080 Ok(Some(ev))
1081 }
1082 }
1083}
1084
1085#[cfg(test)]
1086mod tests {
1087 use super::*;
1088 use crate::from_str;
1089
1090 fn collect_events<'de>(parser: &mut TomlParser<'de>) -> Vec<ParseEvent<'de>> {
1092 let mut events = Vec::new();
1093 while let Ok(Some(event)) = parser.next_event() {
1094 events.push(event);
1095 }
1096 events
1097 }
1098
1099 fn format_events(events: &[ParseEvent<'_>]) -> String {
1101 events
1102 .iter()
1103 .map(|e| format!("{:?}", e))
1104 .collect::<Vec<_>>()
1105 .join("\n")
1106 }
1107
1108 #[test]
1109 fn test_simple_key_value() {
1110 let input = r#"
1111name = "test"
1112value = 42
1113"#;
1114 let mut parser = TomlParser::new(input).unwrap();
1115
1116 assert!(matches!(
1118 parser.next_event().unwrap(),
1119 Some(ParseEvent::StructStart(ContainerKind::Object))
1120 ));
1121
1122 assert!(matches!(
1124 parser.next_event().unwrap(),
1125 Some(ParseEvent::FieldKey(key)) if key.name.as_deref() == Some("name")
1126 ));
1127
1128 assert!(matches!(
1130 parser.next_event().unwrap(),
1131 Some(ParseEvent::Scalar(ScalarValue::Str(s))) if s == "test"
1132 ));
1133
1134 assert!(matches!(
1136 parser.next_event().unwrap(),
1137 Some(ParseEvent::FieldKey(key)) if key.name.as_deref() == Some("value")
1138 ));
1139
1140 assert!(matches!(
1142 parser.next_event().unwrap(),
1143 Some(ParseEvent::Scalar(ScalarValue::I64(42)))
1144 ));
1145
1146 assert!(matches!(
1148 parser.next_event().unwrap(),
1149 Some(ParseEvent::StructEnd)
1150 ));
1151
1152 assert!(parser.next_event().unwrap().is_none());
1154 }
1155
1156 #[test]
1157 fn test_table_header() {
1158 let input = r#"
1159[server]
1160host = "localhost"
1161port = 8080
1162"#;
1163 let mut parser = TomlParser::new(input).unwrap();
1164 let events = collect_events(&mut parser);
1165
1166 assert!(matches!(&events[0], ParseEvent::StructStart(_)));
1169 assert!(
1170 matches!(&events[1], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("server"))
1171 );
1172 assert!(matches!(&events[2], ParseEvent::StructStart(_)));
1173 assert!(matches!(&events[3], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("host")));
1174 assert!(matches!(&events[4], ParseEvent::Scalar(ScalarValue::Str(s)) if s == "localhost"));
1175 assert!(matches!(&events[5], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("port")));
1176 assert!(matches!(
1177 &events[6],
1178 ParseEvent::Scalar(ScalarValue::I64(8080))
1179 ));
1180 assert!(matches!(&events[7], ParseEvent::StructEnd)); assert!(matches!(&events[8], ParseEvent::StructEnd)); }
1183
1184 #[test]
1185 fn test_array_table() {
1186 let input = r#"
1187[[servers]]
1188name = "alpha"
1189
1190[[servers]]
1191name = "beta"
1192"#;
1193 let mut parser = TomlParser::new(input).unwrap();
1194 let events = collect_events(&mut parser);
1195
1196 let event_str = format_events(&events);
1207 eprintln!("Events:\n{}", event_str);
1208
1209 assert!(matches!(&events[0], ParseEvent::StructStart(_))); assert!(
1211 matches!(&events[1], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("servers"))
1212 );
1213 assert!(matches!(&events[2], ParseEvent::SequenceStart(_)));
1214 assert!(matches!(&events[3], ParseEvent::StructStart(_))); assert!(matches!(&events[4], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("name")));
1216 assert!(matches!(&events[5], ParseEvent::Scalar(ScalarValue::Str(s)) if s == "alpha"));
1217 assert!(matches!(&events[6], ParseEvent::StructEnd)); assert!(matches!(&events[7], ParseEvent::SequenceEnd)); assert!(
1222 matches!(&events[8], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("servers"))
1223 );
1224 assert!(matches!(&events[9], ParseEvent::SequenceStart(_)));
1225 assert!(matches!(&events[10], ParseEvent::StructStart(_))); assert!(
1227 matches!(&events[11], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("name"))
1228 );
1229 assert!(matches!(&events[12], ParseEvent::Scalar(ScalarValue::Str(s)) if s == "beta"));
1230 }
1231
1232 #[test]
1233 fn test_interleaved_array_table() {
1234 let input = r#"
1236[[servers]]
1237name = "alpha"
1238
1239[database]
1240host = "localhost"
1241
1242[[servers]]
1243name = "beta"
1244"#;
1245 let mut parser = TomlParser::new(input).unwrap();
1246 let events = collect_events(&mut parser);
1247
1248 let event_str = format_events(&events);
1249 eprintln!("Interleaved events:\n{}", event_str);
1250
1251 let mut saw_servers_first = false;
1254 let mut saw_database = false;
1255 let mut saw_servers_second = false;
1256 let mut servers_count = 0;
1257
1258 for event in events.iter() {
1259 if let ParseEvent::FieldKey(k) = event {
1260 if k.name.as_deref() == Some("servers") {
1261 servers_count += 1;
1262 if !saw_database {
1263 saw_servers_first = true;
1264 } else {
1265 saw_servers_second = true;
1266 }
1267 } else if k.name.as_deref() == Some("database") {
1268 saw_database = true;
1269 }
1270 }
1271 }
1272
1273 assert!(saw_servers_first, "Should see servers before database");
1274 assert!(saw_database, "Should see database");
1275 assert!(
1276 saw_servers_second,
1277 "Should see servers reopened after database"
1278 );
1279 assert_eq!(servers_count, 2, "Should have two FieldKey(servers) events");
1280 }
1281
1282 #[test]
1283 fn test_table_reopening() {
1284 let input = r#"
1286[foo.bar]
1287x = 1
1288
1289[foo.baz]
1290z = 3
1291
1292[foo.bar]
1293y = 2
1294"#;
1295 let mut parser = TomlParser::new(input).unwrap();
1296 let events = collect_events(&mut parser);
1297
1298 let event_str = format_events(&events);
1299 eprintln!("Table reopen events:\n{}", event_str);
1300
1301 let bar_count = events
1303 .iter()
1304 .filter(|e| matches!(e, ParseEvent::FieldKey(k) if k.name.as_deref() == Some("bar")))
1305 .count();
1306
1307 assert_eq!(bar_count, 2, "Should see bar twice (reopened)");
1308 }
1309
1310 #[test]
1311 fn test_dotted_key() {
1312 let input = r#"
1313foo.bar.baz = 1
1314"#;
1315 let mut parser = TomlParser::new(input).unwrap();
1316 let events = collect_events(&mut parser);
1317
1318 let event_str = format_events(&events);
1319 eprintln!("Dotted key events:\n{}", event_str);
1320
1321 assert!(matches!(&events[0], ParseEvent::StructStart(_))); assert!(matches!(&events[1], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("foo")));
1325 assert!(matches!(&events[2], ParseEvent::StructStart(_)));
1326 assert!(matches!(&events[3], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("bar")));
1327 assert!(matches!(&events[4], ParseEvent::StructStart(_)));
1328 assert!(matches!(&events[5], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("baz")));
1329 assert!(matches!(
1330 &events[6],
1331 ParseEvent::Scalar(ScalarValue::I64(1))
1332 ));
1333 assert!(matches!(&events[7], ParseEvent::StructEnd));
1335 assert!(matches!(&events[8], ParseEvent::StructEnd));
1336 assert!(matches!(&events[9], ParseEvent::StructEnd));
1337 }
1338
1339 #[test]
1340 fn test_inline_table() {
1341 let input = r#"
1342server = { host = "localhost", port = 8080 }
1343"#;
1344 let mut parser = TomlParser::new(input).unwrap();
1345 let events = collect_events(&mut parser);
1346
1347 let event_str = format_events(&events);
1348 eprintln!("Inline table events:\n{}", event_str);
1349
1350 assert!(matches!(&events[0], ParseEvent::StructStart(_))); assert!(
1352 matches!(&events[1], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("server"))
1353 );
1354 assert!(matches!(&events[2], ParseEvent::StructStart(_))); assert!(matches!(&events[3], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("host")));
1356 assert!(matches!(&events[4], ParseEvent::Scalar(ScalarValue::Str(s)) if s == "localhost"));
1357 assert!(matches!(&events[5], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("port")));
1358 assert!(matches!(
1359 &events[6],
1360 ParseEvent::Scalar(ScalarValue::I64(8080))
1361 ));
1362 assert!(matches!(&events[7], ParseEvent::StructEnd)); assert!(matches!(&events[8], ParseEvent::StructEnd)); }
1365
1366 #[test]
1367 fn test_inline_array() {
1368 let input = r#"
1369numbers = [1, 2, 3]
1370"#;
1371 let mut parser = TomlParser::new(input).unwrap();
1372 let events = collect_events(&mut parser);
1373
1374 let event_str = format_events(&events);
1375 eprintln!("Inline array events:\n{}", event_str);
1376
1377 assert!(matches!(&events[0], ParseEvent::StructStart(_))); assert!(
1379 matches!(&events[1], ParseEvent::FieldKey(k) if k.name.as_deref() == Some("numbers"))
1380 );
1381 assert!(matches!(&events[2], ParseEvent::SequenceStart(_)));
1382 assert!(matches!(
1383 &events[3],
1384 ParseEvent::Scalar(ScalarValue::I64(1))
1385 ));
1386 assert!(matches!(
1387 &events[4],
1388 ParseEvent::Scalar(ScalarValue::I64(2))
1389 ));
1390 assert!(matches!(
1391 &events[5],
1392 ParseEvent::Scalar(ScalarValue::I64(3))
1393 ));
1394 assert!(matches!(&events[6], ParseEvent::SequenceEnd));
1395 assert!(matches!(&events[7], ParseEvent::StructEnd)); }
1397
1398 #[test]
1403 fn test_deserialize_simple_struct() {
1404 #[derive(Debug, PartialEq, facet::Facet)]
1405 struct Config {
1406 name: String,
1407 port: i64,
1408 enabled: bool,
1409 }
1410
1411 let input = r#"
1412name = "myapp"
1413port = 8080
1414enabled = true
1415"#;
1416 let config: Config = from_str(input).unwrap();
1417 assert_eq!(config.name, "myapp");
1418 assert_eq!(config.port, 8080);
1419 assert!(config.enabled);
1420 }
1421
1422 #[test]
1423 fn test_deserialize_nested_table() {
1424 #[derive(Debug, PartialEq, facet::Facet)]
1425 struct Config {
1426 server: Server,
1427 }
1428
1429 #[derive(Debug, PartialEq, facet::Facet)]
1430 struct Server {
1431 host: String,
1432 port: i64,
1433 }
1434
1435 let input = r#"
1436[server]
1437host = "localhost"
1438port = 3000
1439"#;
1440 let config: Config = from_str(input).unwrap();
1441 assert_eq!(config.server.host, "localhost");
1442 assert_eq!(config.server.port, 3000);
1443 }
1444
1445 #[test]
1446 fn test_deserialize_array_table() {
1447 #[derive(Debug, PartialEq, facet::Facet)]
1448 struct Config {
1449 servers: Vec<Server>,
1450 }
1451
1452 #[derive(Debug, PartialEq, facet::Facet)]
1453 struct Server {
1454 name: String,
1455 }
1456
1457 let input = r#"
1458[[servers]]
1459name = "alpha"
1460
1461[[servers]]
1462name = "beta"
1463
1464[[servers]]
1465name = "gamma"
1466"#;
1467 let config: Config = from_str(input).unwrap();
1468 assert_eq!(config.servers.len(), 3);
1469 assert_eq!(config.servers[0].name, "alpha");
1470 assert_eq!(config.servers[1].name, "beta");
1471 assert_eq!(config.servers[2].name, "gamma");
1472 }
1473
1474 #[test]
1475 fn test_deserialize_interleaved_array_table() {
1476 #[derive(Debug, PartialEq, facet::Facet)]
1477 struct Config {
1478 servers: Vec<Server>,
1479 database: Database,
1480 }
1481
1482 #[derive(Debug, PartialEq, facet::Facet)]
1483 struct Server {
1484 name: String,
1485 }
1486
1487 #[derive(Debug, PartialEq, facet::Facet)]
1488 struct Database {
1489 host: String,
1490 }
1491
1492 let input = r#"
1493[[servers]]
1494name = "alpha"
1495
1496[database]
1497host = "localhost"
1498
1499[[servers]]
1500name = "beta"
1501"#;
1502 let config: Config = from_str(input).unwrap();
1503 assert_eq!(config.servers.len(), 2);
1504 assert_eq!(config.servers[0].name, "alpha");
1505 assert_eq!(config.servers[1].name, "beta");
1506 assert_eq!(config.database.host, "localhost");
1507 }
1508
1509 #[test]
1510 fn test_issue_1399_array_of_tables_only_parses_last_entry() {
1511 #[derive(Debug, PartialEq, facet::Facet)]
1514 struct Lockfile {
1515 version: Option<u32>,
1516 package: Option<Vec<Package>>,
1517 }
1518
1519 #[derive(Debug, PartialEq, facet::Facet)]
1520 struct Package {
1521 name: String,
1522 version: String,
1523 }
1524
1525 let input = r#"
1526version = 4
1527
1528[[package]]
1529name = "myapp"
1530version = "0.1.0"
1531
1532[[package]]
1533name = "aho-corasick"
1534version = "1.1.2"
1535"#;
1536 let lockfile: Lockfile = from_str(input).unwrap();
1537
1538 assert_eq!(lockfile.version, Some(4));
1539
1540 let packages = lockfile.package.expect("package field should be Some");
1541 assert_eq!(
1542 packages.len(),
1543 2,
1544 "Should parse both package entries, not just the last one"
1545 );
1546
1547 assert_eq!(packages[0].name, "myapp");
1548 assert_eq!(packages[0].version, "0.1.0");
1549
1550 assert_eq!(packages[1].name, "aho-corasick");
1551 assert_eq!(packages[1].version, "1.1.2");
1552 }
1553
1554 #[test]
1555 fn test_deserialize_inline_table() {
1556 #[derive(Debug, PartialEq, facet::Facet)]
1557 struct Config {
1558 point: Point,
1559 }
1560
1561 #[derive(Debug, PartialEq, facet::Facet)]
1562 struct Point {
1563 x: i64,
1564 y: i64,
1565 }
1566
1567 let input = r#"point = { x = 10, y = 20 }"#;
1568 let config: Config = from_str(input).unwrap();
1569 assert_eq!(config.point.x, 10);
1570 assert_eq!(config.point.y, 20);
1571 }
1572
1573 #[test]
1574 fn test_deserialize_inline_array() {
1575 #[derive(Debug, PartialEq, facet::Facet)]
1576 struct Config {
1577 values: Vec<i64>,
1578 }
1579
1580 let input = r#"values = [1, 2, 3, 4, 5]"#;
1581 let config: Config = from_str(input).unwrap();
1582 assert_eq!(config.values, vec![1, 2, 3, 4, 5]);
1583 }
1584
1585 #[test]
1586 fn test_deserialize_dotted_key() {
1587 #[derive(Debug, PartialEq, facet::Facet)]
1588 struct Config {
1589 foo: Foo,
1590 }
1591
1592 #[derive(Debug, PartialEq, facet::Facet)]
1593 struct Foo {
1594 bar: Bar,
1595 }
1596
1597 #[derive(Debug, PartialEq, facet::Facet)]
1598 struct Bar {
1599 baz: i64,
1600 }
1601
1602 let input = r#"foo.bar.baz = 42"#;
1603 let config: Config = from_str(input).unwrap();
1604 assert_eq!(config.foo.bar.baz, 42);
1605 }
1606
1607 #[test]
1611 fn test_deserialize_table_reopening() {
1612 #[derive(Debug, PartialEq, facet::Facet)]
1613 struct Config {
1614 foo: Foo,
1615 }
1616
1617 #[derive(Debug, PartialEq, facet::Facet)]
1618 struct Foo {
1619 bar: Bar,
1620 baz: Baz,
1621 }
1622
1623 #[derive(Debug, PartialEq, facet::Facet)]
1624 struct Bar {
1625 x: i64,
1626 y: i64,
1627 }
1628
1629 #[derive(Debug, PartialEq, facet::Facet)]
1630 struct Baz {
1631 z: i64,
1632 }
1633
1634 let input = r#"
1635[foo.bar]
1636x = 1
1637
1638[foo.baz]
1639z = 3
1640
1641[foo.bar]
1642y = 2
1643"#;
1644 let config: Config = from_str(input).unwrap();
1645 assert_eq!(config.foo.bar.x, 1);
1646 assert_eq!(config.foo.bar.y, 2);
1647 assert_eq!(config.foo.baz.z, 3);
1648 }
1649}