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 fn new() -> Self {
67 Self { error: None }
68 }
69
70 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 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 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(
316 &self,
317 target_names: &[Cow<'de, str>],
318 ) -> (Vec<ParseEvent<'de>>, Vec<PathSegment<'de>>) {
319 let mut events = Vec::new();
320
321 let common_len = self
323 .current_path
324 .iter()
325 .zip(target_names.iter())
326 .take_while(|(seg, name)| &seg.name == *name)
327 .count();
328
329 for segment in self.current_path[common_len..].iter().rev() {
331 events.push(Self::end_event_for_segment(segment));
332 }
333
334 let mut new_path: Vec<PathSegment<'de>> = self.current_path[..common_len].to_vec();
336 for name in &target_names[common_len..] {
337 events.push(ParseEvent::FieldKey(FieldKey::new(
338 name.clone(),
339 FieldLocationHint::KeyValue,
340 )));
341 events.push(ParseEvent::StructStart(ContainerKind::Object));
342 new_path.push(PathSegment {
343 name: name.clone(),
344 kind: SegmentKind::Table,
345 });
346 }
347
348 (events, new_path)
349 }
350
351 fn compute_navigation_to_array_table(
360 &self,
361 target_names: &[Cow<'de, str>],
362 ) -> (Vec<ParseEvent<'de>>, Vec<PathSegment<'de>>) {
363 let mut events = Vec::new();
364
365 let common_len = self
370 .current_path
371 .iter()
372 .zip(target_names.iter())
373 .take_while(|(seg, name)| {
374 if matches!(seg.kind, SegmentKind::Array | SegmentKind::ArrayElement) {
376 return false;
377 }
378 &seg.name == *name
379 })
380 .count();
381
382 for segment in self.current_path[common_len..].iter().rev() {
384 events.push(Self::end_event_for_segment(segment));
385 }
386
387 let mut new_path: Vec<PathSegment<'de>> = self.current_path[..common_len].to_vec();
389
390 if target_names.len() > common_len {
391 for name in &target_names[common_len..target_names.len() - 1] {
393 events.push(ParseEvent::FieldKey(FieldKey::new(
394 name.clone(),
395 FieldLocationHint::KeyValue,
396 )));
397 events.push(ParseEvent::StructStart(ContainerKind::Object));
398 new_path.push(PathSegment {
399 name: name.clone(),
400 kind: SegmentKind::Table,
401 });
402 }
403
404 let array_name = target_names.last().unwrap();
406 events.push(ParseEvent::FieldKey(FieldKey::new(
407 array_name.clone(),
408 FieldLocationHint::KeyValue,
409 )));
410 events.push(ParseEvent::SequenceStart(ContainerKind::Array));
411 events.push(ParseEvent::StructStart(ContainerKind::Object));
412
413 new_path.push(PathSegment {
414 name: array_name.clone(),
415 kind: SegmentKind::Array,
416 });
417 new_path.push(PathSegment {
418 name: array_name.clone(),
419 kind: SegmentKind::ArrayElement,
420 });
421 }
422
423 (events, new_path)
424 }
425
426 fn produce_event(&mut self) -> Result<Option<ParseEvent<'de>>, TomlError> {
428 if let Some(event) = self.pending_events.pop_front() {
430 return Ok(Some(event));
431 }
432
433 if !self.inline_stack.is_empty() {
435 return self.produce_inline_event();
436 }
437
438 if !self.root_started {
440 self.root_started = true;
441 return Ok(Some(ParseEvent::StructStart(ContainerKind::Object)));
442 }
443
444 let Some(event) = self.peek_raw() else {
446 if self.root_ended {
448 return Ok(None);
449 }
450
451 for segment in self.current_path.iter().rev() {
453 self.pending_events
454 .push_back(Self::end_event_for_segment(segment));
455 }
456 self.current_path.clear();
457
458 self.pending_events.push_back(ParseEvent::StructEnd);
460 self.root_ended = true;
461
462 return Ok(self.pending_events.pop_front());
463 };
464
465 match event.kind() {
466 EventKind::StdTableOpen => {
467 self.next_raw(); let path = self.parse_dotted_key();
470
471 if let Some(close) = self.peek_raw()
473 && matches!(close.kind(), EventKind::StdTableClose)
474 {
475 self.next_raw();
476 }
477
478 let (nav_events, new_path) = self.compute_navigation_to_table(&path);
480 for e in nav_events {
481 self.pending_events.push_back(e);
482 }
483 self.current_path = new_path;
484
485 if self.pending_events.is_empty() {
487 return self.produce_event();
488 }
489
490 Ok(self.pending_events.pop_front())
491 }
492
493 EventKind::ArrayTableOpen => {
494 self.next_raw(); let path = self.parse_dotted_key();
497
498 if let Some(close) = self.peek_raw()
500 && matches!(close.kind(), EventKind::ArrayTableClose)
501 {
502 self.next_raw();
503 }
504
505 let (nav_events, new_path) = self.compute_navigation_to_array_table(&path);
507 for e in nav_events {
508 self.pending_events.push_back(e);
509 }
510 self.current_path = new_path;
511
512 Ok(self.pending_events.pop_front())
513 }
514
515 EventKind::SimpleKey => {
516 let key_parts = self.parse_dotted_key();
518
519 if let Some(sep) = self.peek_raw()
521 && matches!(sep.kind(), EventKind::KeyValSep)
522 {
523 self.next_raw();
524 }
525
526 if key_parts.len() > 1 {
529 for name in &key_parts[..key_parts.len() - 1] {
531 self.pending_events
532 .push_back(ParseEvent::FieldKey(FieldKey::new(
533 name.clone(),
534 FieldLocationHint::KeyValue,
535 )));
536 self.pending_events
537 .push_back(ParseEvent::StructStart(ContainerKind::Object));
538 }
539
540 let final_key = key_parts.last().unwrap();
542 self.pending_events
543 .push_back(ParseEvent::FieldKey(FieldKey::new(
544 final_key.clone(),
545 FieldLocationHint::KeyValue,
546 )));
547
548 let inline_depth_before = self.inline_stack.len();
550
551 self.parse_value_into_pending()?;
553
554 let entered_inline_container = self.inline_stack.len() > inline_depth_before;
556
557 if entered_inline_container {
558 let num_deferred = key_parts.len() - 1;
560 if let Some((_, deferred_closes)) = self.inline_stack.last_mut() {
561 *deferred_closes += num_deferred;
562 }
563 } else {
564 for _ in 0..key_parts.len() - 1 {
566 self.pending_events.push_back(ParseEvent::StructEnd);
567 }
568 }
569
570 Ok(self.pending_events.pop_front())
571 } else {
572 let key = key_parts.into_iter().next().unwrap();
574 self.pending_events
575 .push_back(ParseEvent::FieldKey(FieldKey::new(
576 key,
577 FieldLocationHint::KeyValue,
578 )));
579
580 self.parse_value_into_pending()?;
582
583 Ok(self.pending_events.pop_front())
584 }
585 }
586
587 EventKind::Error => {
588 let span_str = self.get_span_str(event);
589 Err(TomlError::without_span(TomlErrorKind::Parse(
590 span_str.to_string(),
591 )))
592 }
593
594 _ => {
595 self.next_raw();
597 self.produce_event()
598 }
599 }
600 }
601
602 fn parse_value_into_pending(&mut self) -> Result<(), TomlError> {
604 let Some(event) = self.peek_raw() else {
605 return Err(TomlError::without_span(TomlErrorKind::UnexpectedEof {
606 expected: "value",
607 }));
608 };
609
610 match event.kind() {
611 EventKind::Scalar => {
612 let scalar = self.decode_scalar(event)?;
613 let span = event.span();
615 self.last_scalar_span = Some(facet_reflect::Span::new(
616 span.start(),
617 span.end() - span.start(),
618 ));
619 self.next_raw();
620 self.pending_events.push_back(ParseEvent::Scalar(scalar));
621 }
622
623 EventKind::InlineTableOpen => {
624 self.next_raw();
625 self.pending_events
626 .push_back(ParseEvent::StructStart(ContainerKind::Object));
627 self.inline_stack.push((true, 0)); }
629
630 EventKind::ArrayOpen => {
631 self.next_raw();
632 self.pending_events
633 .push_back(ParseEvent::SequenceStart(ContainerKind::Array));
634 self.inline_stack.push((false, 0)); }
636
637 _ => {
638 return Err(TomlError::without_span(TomlErrorKind::UnexpectedType {
639 expected: "value",
640 got: "unexpected token",
641 }));
642 }
643 }
644
645 Ok(())
646 }
647
648 fn produce_inline_event(&mut self) -> Result<Option<ParseEvent<'de>>, TomlError> {
650 if let Some(event) = self.pending_events.pop_front() {
652 return Ok(Some(event));
653 }
654
655 let (is_inline_table, _deferred_closes) = *self.inline_stack.last().unwrap();
656
657 let Some(event) = self.peek_raw() else {
658 return Err(TomlError::without_span(TomlErrorKind::UnexpectedEof {
659 expected: if is_inline_table { "}" } else { "]" },
660 }));
661 };
662
663 match event.kind() {
664 EventKind::InlineTableClose if is_inline_table => {
665 self.next_raw();
666 let (_, deferred_closes) = self.inline_stack.pop().unwrap();
667 self.pending_events.push_back(ParseEvent::StructEnd);
669 for _ in 0..deferred_closes {
671 self.pending_events.push_back(ParseEvent::StructEnd);
672 }
673 Ok(self.pending_events.pop_front())
674 }
675
676 EventKind::ArrayClose if !is_inline_table => {
677 self.next_raw();
678 let (_, deferred_closes) = self.inline_stack.pop().unwrap();
679 self.pending_events.push_back(ParseEvent::SequenceEnd);
681 for _ in 0..deferred_closes {
683 self.pending_events.push_back(ParseEvent::StructEnd);
684 }
685 Ok(self.pending_events.pop_front())
686 }
687
688 EventKind::ValueSep => {
689 self.next_raw();
691 self.produce_inline_event()
692 }
693
694 EventKind::SimpleKey if is_inline_table => {
695 let key_parts = self.parse_dotted_key();
697
698 if let Some(sep) = self.peek_raw()
700 && matches!(sep.kind(), EventKind::KeyValSep)
701 {
702 self.next_raw();
703 }
704
705 if key_parts.len() > 1 {
707 for name in &key_parts[..key_parts.len() - 1] {
708 self.pending_events
709 .push_back(ParseEvent::FieldKey(FieldKey::new(
710 name.clone(),
711 FieldLocationHint::KeyValue,
712 )));
713 self.pending_events
714 .push_back(ParseEvent::StructStart(ContainerKind::Object));
715 }
716
717 let final_key = key_parts.last().unwrap();
718 self.pending_events
719 .push_back(ParseEvent::FieldKey(FieldKey::new(
720 final_key.clone(),
721 FieldLocationHint::KeyValue,
722 )));
723
724 let inline_depth_before = self.inline_stack.len();
726
727 self.parse_value_into_pending()?;
728
729 let entered_inline_container = self.inline_stack.len() > inline_depth_before;
731
732 if entered_inline_container {
733 let num_deferred = key_parts.len() - 1;
735 if let Some((_, deferred_closes)) = self.inline_stack.last_mut() {
736 *deferred_closes += num_deferred;
737 }
738 } else {
739 for _ in 0..key_parts.len() - 1 {
741 self.pending_events.push_back(ParseEvent::StructEnd);
742 }
743 }
744
745 Ok(self.pending_events.pop_front())
746 } else {
747 let key = key_parts.into_iter().next().unwrap();
748 self.pending_events
749 .push_back(ParseEvent::FieldKey(FieldKey::new(
750 key,
751 FieldLocationHint::KeyValue,
752 )));
753 self.parse_value_into_pending()?;
754 Ok(self.pending_events.pop_front())
755 }
756 }
757
758 EventKind::Scalar if !is_inline_table => {
759 let scalar = self.decode_scalar(event)?;
761 let span = event.span();
763 self.last_scalar_span = Some(facet_reflect::Span::new(
764 span.start(),
765 span.end() - span.start(),
766 ));
767 self.next_raw();
768 Ok(Some(ParseEvent::Scalar(scalar)))
769 }
770
771 EventKind::InlineTableOpen if !is_inline_table => {
772 self.next_raw();
774 self.inline_stack.push((true, 0));
775 Ok(Some(ParseEvent::StructStart(ContainerKind::Object)))
776 }
777
778 EventKind::ArrayOpen if !is_inline_table => {
779 self.next_raw();
781 self.inline_stack.push((false, 0));
782 Ok(Some(ParseEvent::SequenceStart(ContainerKind::Array)))
783 }
784
785 _ => {
786 self.next_raw();
788 self.produce_inline_event()
789 }
790 }
791 }
792
793 fn skip_current_value(&mut self) -> Result<(), TomlError> {
801 let Some(event) = self.produce_event()? else {
803 return Ok(());
804 };
805
806 match event {
807 ParseEvent::Scalar(_) => {
808 Ok(())
810 }
811 ParseEvent::StructStart(_) => {
812 let mut depth = 1;
814 while depth > 0 {
815 let Some(event) = self.produce_event()? else {
816 return Err(TomlError::without_span(TomlErrorKind::UnexpectedEof {
817 expected: "struct end",
818 }));
819 };
820 match event {
821 ParseEvent::StructStart(_) => depth += 1,
822 ParseEvent::StructEnd => depth -= 1,
823 _ => {}
824 }
825 }
826 Ok(())
827 }
828 ParseEvent::SequenceStart(_) => {
829 let mut depth = 1;
831 while depth > 0 {
832 let Some(event) = self.produce_event()? else {
833 return Err(TomlError::without_span(TomlErrorKind::UnexpectedEof {
834 expected: "sequence end",
835 }));
836 };
837 match event {
838 ParseEvent::SequenceStart(_) => depth += 1,
839 ParseEvent::SequenceEnd => depth -= 1,
840 _ => {}
841 }
842 }
843 Ok(())
844 }
845 _ => {
846 Ok(())
848 }
849 }
850 }
851
852 fn build_probe(&self) -> Result<Vec<FieldEvidence<'de>>, TomlError> {
854 let mut evidence = Vec::new();
855 let mut pos = self.pos;
856
857 while pos < self.events.len() {
859 let event = &self.events[pos];
860
861 if Self::should_skip(event) {
862 pos += 1;
863 continue;
864 }
865
866 match event.kind() {
867 EventKind::SimpleKey => {
868 let key = self.decode_key(event);
869 pos += 1;
870
871 while pos < self.events.len() {
873 let e = &self.events[pos];
874 if !Self::should_skip(e) {
875 break;
876 }
877 pos += 1;
878 }
879
880 while pos < self.events.len() {
882 let e = &self.events[pos];
883 if Self::should_skip(e) {
884 pos += 1;
885 continue;
886 }
887 if matches!(e.kind(), EventKind::KeySep | EventKind::SimpleKey) {
888 pos += 1;
889 continue;
890 }
891 break;
892 }
893
894 if pos < self.events.len() {
896 let e = &self.events[pos];
897 if matches!(e.kind(), EventKind::KeyValSep) {
898 pos += 1;
899 }
900 }
901
902 while pos < self.events.len() {
904 let e = &self.events[pos];
905 if !Self::should_skip(e) {
906 break;
907 }
908 pos += 1;
909 }
910
911 let scalar_value = if pos < self.events.len() {
913 let e = &self.events[pos];
914 if matches!(e.kind(), EventKind::Scalar) {
915 self.decode_scalar(e).ok()
916 } else {
917 None
918 }
919 } else {
920 None
921 };
922
923 if let Some(sv) = scalar_value {
924 evidence.push(FieldEvidence::with_scalar_value(
925 key,
926 FieldLocationHint::KeyValue,
927 None,
928 sv,
929 None,
930 ));
931 } else {
932 evidence.push(FieldEvidence::new(
933 key,
934 FieldLocationHint::KeyValue,
935 None,
936 None,
937 ));
938 }
939 }
940
941 EventKind::StdTableOpen
942 | EventKind::ArrayTableOpen
943 | EventKind::InlineTableClose
944 | EventKind::ArrayClose => {
945 break;
947 }
948
949 _ => {
950 pos += 1;
951 }
952 }
953 }
954
955 Ok(evidence)
956 }
957}
958
959impl<'de> FormatParser<'de> for TomlParser<'de> {
960 type Error = TomlError;
961 type Probe<'a>
962 = TomlProbe<'de>
963 where
964 Self: 'a;
965
966 fn next_event(&mut self) -> Result<Option<ParseEvent<'de>>, Self::Error> {
967 if let Some(event) = self.event_peek.take() {
968 return Ok(Some(event));
969 }
970 self.produce_event()
971 }
972
973 fn peek_event(&mut self) -> Result<Option<ParseEvent<'de>>, Self::Error> {
974 if let Some(event) = self.event_peek.clone() {
975 return Ok(Some(event));
976 }
977 let event = self.produce_event()?;
978 if let Some(ref e) = event {
979 self.event_peek = Some(e.clone());
980 }
981 Ok(event)
982 }
983
984 fn skip_value(&mut self) -> Result<(), Self::Error> {
985 debug_assert!(
986 self.event_peek.is_none(),
987 "skip_value called while an event is buffered"
988 );
989 self.skip_current_value()
990 }
991
992 fn begin_probe(&mut self) -> Result<Self::Probe<'_>, Self::Error> {
993 let evidence = self.build_probe()?;
994 Ok(TomlProbe { evidence, idx: 0 })
995 }
996
997 fn capture_raw(&mut self) -> Result<Option<&'de str>, Self::Error> {
998 self.skip_value()?;
1000 Ok(None)
1001 }
1002
1003 fn current_span(&self) -> Option<facet_reflect::Span> {
1004 self.last_scalar_span
1005 }
1006}
1007
1008pub struct TomlProbe<'de> {
1010 evidence: Vec<FieldEvidence<'de>>,
1011 idx: usize,
1012}
1013
1014impl<'de> ProbeStream<'de> for TomlProbe<'de> {
1015 type Error = TomlError;
1016
1017 fn next(&mut self) -> Result<Option<FieldEvidence<'de>>, Self::Error> {
1018 if self.idx >= self.evidence.len() {
1019 Ok(None)
1020 } else {
1021 let ev = self.evidence[self.idx].clone();
1022 self.idx += 1;
1023 Ok(Some(ev))
1024 }
1025 }
1026}
1027
1028pub fn from_str<'de, T>(input: &'de str) -> Result<T, TomlError>
1034where
1035 T: facet_core::Facet<'de>,
1036{
1037 let parser = TomlParser::new(input)?;
1038 let mut deserializer = facet_format::FormatDeserializer::new(parser);
1039
1040 deserializer.deserialize().map_err(|e| {
1041 let err = match e {
1042 facet_format::DeserializeError::Parser(e) => e,
1043 facet_format::DeserializeError::Reflect { ref error, span } => {
1044 let mut toml_err = TomlError::from(error.clone());
1045 if span.is_some() {
1047 toml_err.span = span;
1048 }
1049 toml_err
1050 }
1051 facet_format::DeserializeError::UnexpectedEof { expected } => {
1052 TomlError::without_span(TomlErrorKind::UnexpectedEof { expected })
1053 }
1054 facet_format::DeserializeError::Unsupported(msg) => {
1055 TomlError::without_span(TomlErrorKind::InvalidValue { message: msg })
1056 }
1057 facet_format::DeserializeError::TypeMismatch { expected, got } => {
1058 TomlError::without_span(TomlErrorKind::InvalidValue {
1059 message: alloc::format!("type mismatch: expected {}, got {}", expected, got),
1060 })
1061 }
1062 facet_format::DeserializeError::UnknownField(field) => {
1063 TomlError::without_span(TomlErrorKind::UnknownField {
1064 field,
1065 expected: Vec::new(),
1066 suggestion: None,
1067 })
1068 }
1069 facet_format::DeserializeError::CannotBorrow { message, .. } => {
1070 TomlError::without_span(TomlErrorKind::InvalidValue { message })
1071 }
1072 facet_format::DeserializeError::MissingField { field, .. } => {
1073 TomlError::without_span(TomlErrorKind::MissingField {
1074 field,
1075 table_start: None,
1076 table_end: None,
1077 })
1078 }
1079 };
1080 err.with_source(input)
1082 })
1083}
1084
1085#[cfg(test)]
1086mod tests {
1087 use super::*;
1088
1089 fn collect_events<'de>(parser: &mut TomlParser<'de>) -> Vec<ParseEvent<'de>> {
1091 let mut events = Vec::new();
1092 while let Ok(Some(event)) = parser.next_event() {
1093 events.push(event);
1094 }
1095 events
1096 }
1097
1098 fn format_events(events: &[ParseEvent<'_>]) -> String {
1100 events
1101 .iter()
1102 .map(|e| format!("{:?}", e))
1103 .collect::<Vec<_>>()
1104 .join("\n")
1105 }
1106
1107 #[test]
1108 fn test_simple_key_value() {
1109 let input = r#"
1110name = "test"
1111value = 42
1112"#;
1113 let mut parser = TomlParser::new(input).unwrap();
1114
1115 assert!(matches!(
1117 parser.next_event().unwrap(),
1118 Some(ParseEvent::StructStart(ContainerKind::Object))
1119 ));
1120
1121 assert!(matches!(
1123 parser.next_event().unwrap(),
1124 Some(ParseEvent::FieldKey(key)) if key.name == "name"
1125 ));
1126
1127 assert!(matches!(
1129 parser.next_event().unwrap(),
1130 Some(ParseEvent::Scalar(ScalarValue::Str(s))) if s == "test"
1131 ));
1132
1133 assert!(matches!(
1135 parser.next_event().unwrap(),
1136 Some(ParseEvent::FieldKey(key)) if key.name == "value"
1137 ));
1138
1139 assert!(matches!(
1141 parser.next_event().unwrap(),
1142 Some(ParseEvent::Scalar(ScalarValue::I64(42)))
1143 ));
1144
1145 assert!(matches!(
1147 parser.next_event().unwrap(),
1148 Some(ParseEvent::StructEnd)
1149 ));
1150
1151 assert!(parser.next_event().unwrap().is_none());
1153 }
1154
1155 #[test]
1156 fn test_table_header() {
1157 let input = r#"
1158[server]
1159host = "localhost"
1160port = 8080
1161"#;
1162 let mut parser = TomlParser::new(input).unwrap();
1163 let events = collect_events(&mut parser);
1164
1165 assert!(matches!(&events[0], ParseEvent::StructStart(_)));
1168 assert!(matches!(&events[1], ParseEvent::FieldKey(k) if k.name == "server"));
1169 assert!(matches!(&events[2], ParseEvent::StructStart(_)));
1170 assert!(matches!(&events[3], ParseEvent::FieldKey(k) if k.name == "host"));
1171 assert!(matches!(&events[4], ParseEvent::Scalar(ScalarValue::Str(s)) if s == "localhost"));
1172 assert!(matches!(&events[5], ParseEvent::FieldKey(k) if k.name == "port"));
1173 assert!(matches!(
1174 &events[6],
1175 ParseEvent::Scalar(ScalarValue::I64(8080))
1176 ));
1177 assert!(matches!(&events[7], ParseEvent::StructEnd)); assert!(matches!(&events[8], ParseEvent::StructEnd)); }
1180
1181 #[test]
1182 fn test_array_table() {
1183 let input = r#"
1184[[servers]]
1185name = "alpha"
1186
1187[[servers]]
1188name = "beta"
1189"#;
1190 let mut parser = TomlParser::new(input).unwrap();
1191 let events = collect_events(&mut parser);
1192
1193 let event_str = format_events(&events);
1204 eprintln!("Events:\n{}", event_str);
1205
1206 assert!(matches!(&events[0], ParseEvent::StructStart(_))); assert!(matches!(&events[1], ParseEvent::FieldKey(k) if k.name == "servers"));
1208 assert!(matches!(&events[2], ParseEvent::SequenceStart(_)));
1209 assert!(matches!(&events[3], ParseEvent::StructStart(_))); assert!(matches!(&events[4], ParseEvent::FieldKey(k) if k.name == "name"));
1211 assert!(matches!(&events[5], ParseEvent::Scalar(ScalarValue::Str(s)) if s == "alpha"));
1212 assert!(matches!(&events[6], ParseEvent::StructEnd)); assert!(matches!(&events[7], ParseEvent::SequenceEnd)); assert!(matches!(&events[8], ParseEvent::FieldKey(k) if k.name == "servers"));
1217 assert!(matches!(&events[9], ParseEvent::SequenceStart(_)));
1218 assert!(matches!(&events[10], ParseEvent::StructStart(_))); assert!(matches!(&events[11], ParseEvent::FieldKey(k) if k.name == "name"));
1220 assert!(matches!(&events[12], ParseEvent::Scalar(ScalarValue::Str(s)) if s == "beta"));
1221 }
1222
1223 #[test]
1224 fn test_interleaved_array_table() {
1225 let input = r#"
1227[[servers]]
1228name = "alpha"
1229
1230[database]
1231host = "localhost"
1232
1233[[servers]]
1234name = "beta"
1235"#;
1236 let mut parser = TomlParser::new(input).unwrap();
1237 let events = collect_events(&mut parser);
1238
1239 let event_str = format_events(&events);
1240 eprintln!("Interleaved events:\n{}", event_str);
1241
1242 let mut saw_servers_first = false;
1245 let mut saw_database = false;
1246 let mut saw_servers_second = false;
1247 let mut servers_count = 0;
1248
1249 for event in events.iter() {
1250 if let ParseEvent::FieldKey(k) = event {
1251 if k.name == "servers" {
1252 servers_count += 1;
1253 if !saw_database {
1254 saw_servers_first = true;
1255 } else {
1256 saw_servers_second = true;
1257 }
1258 } else if k.name == "database" {
1259 saw_database = true;
1260 }
1261 }
1262 }
1263
1264 assert!(saw_servers_first, "Should see servers before database");
1265 assert!(saw_database, "Should see database");
1266 assert!(
1267 saw_servers_second,
1268 "Should see servers reopened after database"
1269 );
1270 assert_eq!(servers_count, 2, "Should have two FieldKey(servers) events");
1271 }
1272
1273 #[test]
1274 fn test_table_reopening() {
1275 let input = r#"
1277[foo.bar]
1278x = 1
1279
1280[foo.baz]
1281z = 3
1282
1283[foo.bar]
1284y = 2
1285"#;
1286 let mut parser = TomlParser::new(input).unwrap();
1287 let events = collect_events(&mut parser);
1288
1289 let event_str = format_events(&events);
1290 eprintln!("Table reopen events:\n{}", event_str);
1291
1292 let bar_count = events
1294 .iter()
1295 .filter(|e| matches!(e, ParseEvent::FieldKey(k) if k.name == "bar"))
1296 .count();
1297
1298 assert_eq!(bar_count, 2, "Should see bar twice (reopened)");
1299 }
1300
1301 #[test]
1302 fn test_dotted_key() {
1303 let input = r#"
1304foo.bar.baz = 1
1305"#;
1306 let mut parser = TomlParser::new(input).unwrap();
1307 let events = collect_events(&mut parser);
1308
1309 let event_str = format_events(&events);
1310 eprintln!("Dotted key events:\n{}", event_str);
1311
1312 assert!(matches!(&events[0], ParseEvent::StructStart(_))); assert!(matches!(&events[1], ParseEvent::FieldKey(k) if k.name == "foo"));
1316 assert!(matches!(&events[2], ParseEvent::StructStart(_)));
1317 assert!(matches!(&events[3], ParseEvent::FieldKey(k) if k.name == "bar"));
1318 assert!(matches!(&events[4], ParseEvent::StructStart(_)));
1319 assert!(matches!(&events[5], ParseEvent::FieldKey(k) if k.name == "baz"));
1320 assert!(matches!(
1321 &events[6],
1322 ParseEvent::Scalar(ScalarValue::I64(1))
1323 ));
1324 assert!(matches!(&events[7], ParseEvent::StructEnd));
1326 assert!(matches!(&events[8], ParseEvent::StructEnd));
1327 assert!(matches!(&events[9], ParseEvent::StructEnd));
1328 }
1329
1330 #[test]
1331 fn test_inline_table() {
1332 let input = r#"
1333server = { host = "localhost", port = 8080 }
1334"#;
1335 let mut parser = TomlParser::new(input).unwrap();
1336 let events = collect_events(&mut parser);
1337
1338 let event_str = format_events(&events);
1339 eprintln!("Inline table events:\n{}", event_str);
1340
1341 assert!(matches!(&events[0], ParseEvent::StructStart(_))); assert!(matches!(&events[1], ParseEvent::FieldKey(k) if k.name == "server"));
1343 assert!(matches!(&events[2], ParseEvent::StructStart(_))); assert!(matches!(&events[3], ParseEvent::FieldKey(k) if k.name == "host"));
1345 assert!(matches!(&events[4], ParseEvent::Scalar(ScalarValue::Str(s)) if s == "localhost"));
1346 assert!(matches!(&events[5], ParseEvent::FieldKey(k) if k.name == "port"));
1347 assert!(matches!(
1348 &events[6],
1349 ParseEvent::Scalar(ScalarValue::I64(8080))
1350 ));
1351 assert!(matches!(&events[7], ParseEvent::StructEnd)); assert!(matches!(&events[8], ParseEvent::StructEnd)); }
1354
1355 #[test]
1356 fn test_inline_array() {
1357 let input = r#"
1358numbers = [1, 2, 3]
1359"#;
1360 let mut parser = TomlParser::new(input).unwrap();
1361 let events = collect_events(&mut parser);
1362
1363 let event_str = format_events(&events);
1364 eprintln!("Inline array events:\n{}", event_str);
1365
1366 assert!(matches!(&events[0], ParseEvent::StructStart(_))); assert!(matches!(&events[1], ParseEvent::FieldKey(k) if k.name == "numbers"));
1368 assert!(matches!(&events[2], ParseEvent::SequenceStart(_)));
1369 assert!(matches!(
1370 &events[3],
1371 ParseEvent::Scalar(ScalarValue::I64(1))
1372 ));
1373 assert!(matches!(
1374 &events[4],
1375 ParseEvent::Scalar(ScalarValue::I64(2))
1376 ));
1377 assert!(matches!(
1378 &events[5],
1379 ParseEvent::Scalar(ScalarValue::I64(3))
1380 ));
1381 assert!(matches!(&events[6], ParseEvent::SequenceEnd));
1382 assert!(matches!(&events[7], ParseEvent::StructEnd)); }
1384
1385 #[test]
1390 fn test_deserialize_simple_struct() {
1391 #[derive(Debug, PartialEq, facet::Facet)]
1392 struct Config {
1393 name: String,
1394 port: i64,
1395 enabled: bool,
1396 }
1397
1398 let input = r#"
1399name = "myapp"
1400port = 8080
1401enabled = true
1402"#;
1403 let config: Config = from_str(input).unwrap();
1404 assert_eq!(config.name, "myapp");
1405 assert_eq!(config.port, 8080);
1406 assert!(config.enabled);
1407 }
1408
1409 #[test]
1410 fn test_deserialize_nested_table() {
1411 #[derive(Debug, PartialEq, facet::Facet)]
1412 struct Config {
1413 server: Server,
1414 }
1415
1416 #[derive(Debug, PartialEq, facet::Facet)]
1417 struct Server {
1418 host: String,
1419 port: i64,
1420 }
1421
1422 let input = r#"
1423[server]
1424host = "localhost"
1425port = 3000
1426"#;
1427 let config: Config = from_str(input).unwrap();
1428 assert_eq!(config.server.host, "localhost");
1429 assert_eq!(config.server.port, 3000);
1430 }
1431
1432 #[test]
1433 fn test_deserialize_array_table() {
1434 #[derive(Debug, PartialEq, facet::Facet)]
1435 struct Config {
1436 servers: Vec<Server>,
1437 }
1438
1439 #[derive(Debug, PartialEq, facet::Facet)]
1440 struct Server {
1441 name: String,
1442 }
1443
1444 let input = r#"
1445[[servers]]
1446name = "alpha"
1447
1448[[servers]]
1449name = "beta"
1450
1451[[servers]]
1452name = "gamma"
1453"#;
1454 let config: Config = from_str(input).unwrap();
1455 assert_eq!(config.servers.len(), 3);
1456 assert_eq!(config.servers[0].name, "alpha");
1457 assert_eq!(config.servers[1].name, "beta");
1458 assert_eq!(config.servers[2].name, "gamma");
1459 }
1460
1461 #[test]
1462 fn test_deserialize_interleaved_array_table() {
1463 #[derive(Debug, PartialEq, facet::Facet)]
1464 struct Config {
1465 servers: Vec<Server>,
1466 database: Database,
1467 }
1468
1469 #[derive(Debug, PartialEq, facet::Facet)]
1470 struct Server {
1471 name: String,
1472 }
1473
1474 #[derive(Debug, PartialEq, facet::Facet)]
1475 struct Database {
1476 host: String,
1477 }
1478
1479 let input = r#"
1480[[servers]]
1481name = "alpha"
1482
1483[database]
1484host = "localhost"
1485
1486[[servers]]
1487name = "beta"
1488"#;
1489 let config: Config = from_str(input).unwrap();
1490 assert_eq!(config.servers.len(), 2);
1491 assert_eq!(config.servers[0].name, "alpha");
1492 assert_eq!(config.servers[1].name, "beta");
1493 assert_eq!(config.database.host, "localhost");
1494 }
1495
1496 #[test]
1497 fn test_issue_1399_array_of_tables_only_parses_last_entry() {
1498 #[derive(Debug, PartialEq, facet::Facet)]
1501 struct Lockfile {
1502 version: Option<u32>,
1503 package: Option<Vec<Package>>,
1504 }
1505
1506 #[derive(Debug, PartialEq, facet::Facet)]
1507 struct Package {
1508 name: String,
1509 version: String,
1510 }
1511
1512 let input = r#"
1513version = 4
1514
1515[[package]]
1516name = "myapp"
1517version = "0.1.0"
1518
1519[[package]]
1520name = "aho-corasick"
1521version = "1.1.2"
1522"#;
1523 let lockfile: Lockfile = from_str(input).unwrap();
1524
1525 assert_eq!(lockfile.version, Some(4));
1526
1527 let packages = lockfile.package.expect("package field should be Some");
1528 assert_eq!(
1529 packages.len(),
1530 2,
1531 "Should parse both package entries, not just the last one"
1532 );
1533
1534 assert_eq!(packages[0].name, "myapp");
1535 assert_eq!(packages[0].version, "0.1.0");
1536
1537 assert_eq!(packages[1].name, "aho-corasick");
1538 assert_eq!(packages[1].version, "1.1.2");
1539 }
1540
1541 #[test]
1542 fn test_deserialize_inline_table() {
1543 #[derive(Debug, PartialEq, facet::Facet)]
1544 struct Config {
1545 point: Point,
1546 }
1547
1548 #[derive(Debug, PartialEq, facet::Facet)]
1549 struct Point {
1550 x: i64,
1551 y: i64,
1552 }
1553
1554 let input = r#"point = { x = 10, y = 20 }"#;
1555 let config: Config = from_str(input).unwrap();
1556 assert_eq!(config.point.x, 10);
1557 assert_eq!(config.point.y, 20);
1558 }
1559
1560 #[test]
1561 fn test_deserialize_inline_array() {
1562 #[derive(Debug, PartialEq, facet::Facet)]
1563 struct Config {
1564 values: Vec<i64>,
1565 }
1566
1567 let input = r#"values = [1, 2, 3, 4, 5]"#;
1568 let config: Config = from_str(input).unwrap();
1569 assert_eq!(config.values, vec![1, 2, 3, 4, 5]);
1570 }
1571
1572 #[test]
1573 fn test_deserialize_dotted_key() {
1574 #[derive(Debug, PartialEq, facet::Facet)]
1575 struct Config {
1576 foo: Foo,
1577 }
1578
1579 #[derive(Debug, PartialEq, facet::Facet)]
1580 struct Foo {
1581 bar: Bar,
1582 }
1583
1584 #[derive(Debug, PartialEq, facet::Facet)]
1585 struct Bar {
1586 baz: i64,
1587 }
1588
1589 let input = r#"foo.bar.baz = 42"#;
1590 let config: Config = from_str(input).unwrap();
1591 assert_eq!(config.foo.bar.baz, 42);
1592 }
1593
1594 #[test]
1616 #[ignore = "table reopening requires deferred validation in facet-format"]
1617 fn test_deserialize_table_reopening() {
1618 #[derive(Debug, PartialEq, facet::Facet)]
1619 struct Config {
1620 foo: Foo,
1621 }
1622
1623 #[derive(Debug, PartialEq, facet::Facet)]
1624 struct Foo {
1625 bar: Bar,
1626 baz: Baz,
1627 }
1628
1629 #[derive(Debug, PartialEq, facet::Facet)]
1630 struct Bar {
1631 x: i64,
1632 y: i64,
1633 }
1634
1635 #[derive(Debug, PartialEq, facet::Facet)]
1636 struct Baz {
1637 z: i64,
1638 }
1639
1640 let input = r#"
1641[foo.bar]
1642x = 1
1643
1644[foo.baz]
1645z = 3
1646
1647[foo.bar]
1648y = 2
1649"#;
1650 let config: Config = from_str(input).unwrap();
1651 assert_eq!(config.foo.bar.x, 1);
1652 assert_eq!(config.foo.bar.y, 2);
1653 assert_eq!(config.foo.baz.z, 3);
1654 }
1655}