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    state.open(open_event);
29    while let Some(event) = input.next_token() {
30        close_span = event.span();
31        match event.kind() {
32            EventKind::StdTableOpen
33            | EventKind::ArrayTableOpen
34            | EventKind::InlineTableClose
35            | EventKind::SimpleKey
36            | EventKind::KeySep
37            | EventKind::KeyValSep
38            | EventKind::StdTableClose
39            | EventKind::ArrayTableClose => {
40                #[cfg(feature = "debug")]
41                trace(
42                    &format!("unexpected {event:?}"),
43                    anstyle::AnsiColor::Red.on_default(),
44                );
45                break;
46            }
47            EventKind::Error => {
48                #[cfg(feature = "debug")]
49                trace(
50                    &format!("unexpected {event:?}"),
51                    anstyle::AnsiColor::Red.on_default(),
52                );
53                continue;
54            }
55            EventKind::InlineTableOpen => {
56                let value = on_inline_table(event, input, source, errors);
57                state.capture_value(event, value);
58            }
59            EventKind::ArrayOpen => {
60                let value = on_array(event, input, source, errors);
61                state.capture_value(event, value);
62            }
63            EventKind::Scalar => {
64                let value = on_scalar(event, source, errors);
65                state.capture_value(event, value);
66            }
67            EventKind::ValueSep => {
68                state.finish_value(event, &mut result);
69                state.sep_value(event);
70            }
71            EventKind::Whitespace | EventKind::Comment | EventKind::Newline => {
72                state.whitespace(event);
73            }
74            EventKind::ArrayClose => {
75                state.finish_value(event, &mut result);
76                state.close(open_event, event, &mut result);
77                break;
78            }
79        }
80    }
81
82    let span = open_event.span().start()..close_span.end();
83
84    Spanned::new(span, DeValue::Array(result))
85}
86
87#[derive(Default)]
88struct State<'i> {
89    current_value: Option<Spanned<DeValue<'i>>>,
90    trailing_start: Option<usize>,
91}
92
93impl<'i> State<'i> {
94    fn open(&mut self, _open_event: &toml_parser::parser::Event) {}
95
96    fn whitespace(&mut self, _event: &toml_parser::parser::Event) {}
97
98    fn capture_value(&mut self, _event: &toml_parser::parser::Event, value: Spanned<DeValue<'i>>) {
99        self.trailing_start = None;
100        self.current_value = Some(value);
101    }
102
103    fn finish_value(&mut self, _event: &toml_parser::parser::Event, result: &mut DeArray<'i>) {
104        #[cfg(feature = "debug")]
105        let _scope = TraceScope::new("array::finish_value");
106        if let Some(value) = self.current_value.take() {
107            result.push(value);
108        }
109    }
110
111    fn sep_value(&mut self, event: &toml_parser::parser::Event) {
112        self.trailing_start = Some(event.span().end());
113    }
114
115    fn close(
116        &mut self,
117        _open_event: &toml_parser::parser::Event,
118        _close_event: &toml_parser::parser::Event,
119        _result: &mut DeArray<'i>,
120    ) {
121        #[cfg(feature = "debug")]
122        let _scope = TraceScope::new("array::close");
123    }
124}