toml/de/parser/
array.rs

1use serde_spanned::Spanned;
2
3use crate::de::parser::inline_table::on_inline_table;
4use crate::de::parser::value::on_scalar;
5use crate::de::{DeArray, DeValue};
6
7use crate::de::parser::prelude::*;
8
9/// ```bnf
10/// ;; Array
11///
12/// array = array-open array-values array-close
13/// array-values =  ws-comment-newline val ws-comment-newline array-sep array-values
14/// array-values =/ ws-comment-newline val ws-comment-newline [ array-sep ]
15/// ```
16pub(crate) fn on_array<'i>(
17    open_event: &toml_parser::parser::Event,
18    input: &mut Input<'_>,
19    source: toml_parser::Source<'i>,
20    errors: &mut dyn ErrorSink,
21) -> Spanned<DeValue<'i>> {
22    #[cfg(feature = "debug")]
23    let _scope = TraceScope::new("array::on_array");
24    let mut result = DeArray::new();
25    let mut close_span = open_event.span();
26
27    let mut state = State::default();
28    while let Some(event) = input.next_token() {
29        close_span = event.span();
30        match event.kind() {
31            EventKind::StdTableOpen
32            | EventKind::ArrayTableOpen
33            | EventKind::InlineTableClose
34            | EventKind::SimpleKey
35            | EventKind::KeySep
36            | EventKind::KeyValSep
37            | EventKind::StdTableClose
38            | EventKind::ArrayTableClose => {
39                #[cfg(feature = "debug")]
40                trace(
41                    &format!("unexpected {event:?}"),
42                    anstyle::AnsiColor::Red.on_default(),
43                );
44                break;
45            }
46            EventKind::Error => {
47                #[cfg(feature = "debug")]
48                trace(
49                    &format!("unexpected {event:?}"),
50                    anstyle::AnsiColor::Red.on_default(),
51                );
52                continue;
53            }
54            EventKind::InlineTableOpen => {
55                let value = on_inline_table(event, input, source, errors);
56                state.capture_value(event, value);
57            }
58            EventKind::ArrayOpen => {
59                let value = on_array(event, input, source, errors);
60                state.capture_value(event, value);
61            }
62            EventKind::Scalar => {
63                let value = on_scalar(event, source, errors);
64                state.capture_value(event, value);
65            }
66            EventKind::ValueSep => {
67                state.finish_value(event, &mut result);
68                state.sep_value(event);
69            }
70            EventKind::Whitespace | EventKind::Comment | EventKind::Newline => {
71                state.whitespace(event);
72            }
73            EventKind::ArrayClose => {
74                state.finish_value(event, &mut result);
75                state.close(open_event, event, &mut result);
76                break;
77            }
78        }
79    }
80
81    let span = open_event.span().start()..close_span.end();
82
83    Spanned::new(span, DeValue::Array(result))
84}
85
86#[derive(Default)]
87struct State<'i> {
88    current_value: Option<Spanned<DeValue<'i>>>,
89    trailing_start: Option<usize>,
90}
91
92impl<'i> State<'i> {
93    fn whitespace(&mut self, _event: &toml_parser::parser::Event) {}
94
95    fn capture_value(&mut self, _event: &toml_parser::parser::Event, value: Spanned<DeValue<'i>>) {
96        self.trailing_start = None;
97        self.current_value = Some(value);
98    }
99
100    fn finish_value(&mut self, _event: &toml_parser::parser::Event, result: &mut DeArray<'i>) {
101        #[cfg(feature = "debug")]
102        let _scope = TraceScope::new("array::finish_value");
103        if let Some(value) = self.current_value.take() {
104            result.push(value);
105        }
106    }
107
108    fn sep_value(&mut self, event: &toml_parser::parser::Event) {
109        self.trailing_start = Some(event.span().end());
110    }
111
112    fn close(
113        &mut self,
114        _open_event: &toml_parser::parser::Event,
115        _close_event: &toml_parser::parser::Event,
116        _result: &mut DeArray<'i>,
117    ) {
118        #[cfg(feature = "debug")]
119        let _scope = TraceScope::new("array::close");
120    }
121}