1use crate::key::Key;
2use crate::parser::prelude::*;
3use crate::repr::Decor;
4use crate::repr::Repr;
5use crate::RawString;
6
7pub(crate) fn on_key(
12 key_event: &toml_parser::parser::Event,
13 input: &mut Input<'_>,
14 source: toml_parser::Source<'_>,
15 errors: &mut dyn ErrorSink,
16) -> (Vec<Key>, Option<Key>) {
17 #[cfg(feature = "debug")]
18 let _scope = TraceScope::new("key::on_key");
19 let mut result_path = Vec::new();
20 let mut result_key = None;
21
22 let mut state = State::new(key_event);
23 if more_key(input) {
24 while let Some(event) = input.next_token() {
25 match event.kind() {
26 EventKind::StdTableOpen
27 | EventKind::ArrayTableOpen
28 | EventKind::InlineTableOpen
29 | EventKind::InlineTableClose
30 | EventKind::ArrayOpen
31 | EventKind::ArrayClose
32 | EventKind::Scalar
33 | EventKind::ValueSep
34 | EventKind::Comment
35 | EventKind::Newline
36 | EventKind::KeyValSep
37 | EventKind::StdTableClose
38 | EventKind::ArrayTableClose
39 | EventKind::Error => {
40 #[cfg(feature = "debug")]
41 trace(
42 &format!("unexpected {event:?}"),
43 anstyle::AnsiColor::Red.on_default(),
44 );
45 continue;
46 }
47 EventKind::SimpleKey => {
48 state.current_key = Some(*event);
49
50 if !more_key(input) {
51 break;
52 }
53 }
54 EventKind::Whitespace => {
55 state.whitespace(event);
56 }
57 EventKind::KeySep => {
58 state.close_key(&mut result_path, &mut result_key, source, errors);
59 }
60 }
61 }
62 }
63
64 state.close_key(&mut result_path, &mut result_key, source, errors);
65
66 #[cfg(not(feature = "unbounded"))]
67 if super::LIMIT <= result_path.len() as u32 {
68 errors.report_error(ParseError::new("recursion limit"));
69 return (Vec::new(), None);
70 }
71
72 (result_path, result_key)
73}
74
75fn more_key(input: &Input<'_>) -> bool {
76 let first = input.get(0).map(|e| e.kind());
77 let second = input.get(1).map(|e| e.kind());
78 if first == Some(EventKind::KeySep) {
79 true
80 } else if first == Some(EventKind::Whitespace) && second == Some(EventKind::KeySep) {
81 true
82 } else {
83 false
84 }
85}
86
87struct State {
88 current_prefix: Option<toml_parser::Span>,
89 current_key: Option<toml_parser::parser::Event>,
90 current_suffix: Option<toml_parser::Span>,
91}
92
93impl State {
94 fn new(key_event: &toml_parser::parser::Event) -> Self {
95 Self {
96 current_prefix: None,
97 current_key: Some(*key_event),
98 current_suffix: None,
99 }
100 }
101
102 fn whitespace(&mut self, event: &toml_parser::parser::Event) {
103 if self.current_key.is_some() {
104 self.current_suffix = Some(event.span());
105 } else {
106 self.current_prefix = Some(event.span());
107 }
108 }
109
110 fn close_key(
111 &mut self,
112 result_path: &mut Vec<Key>,
113 result_key: &mut Option<Key>,
114 source: toml_parser::Source<'_>,
115 errors: &mut dyn ErrorSink,
116 ) {
117 let Some(key) = self.current_key.take() else {
118 return;
119 };
120 let prefix_span = self
121 .current_prefix
122 .take()
123 .unwrap_or_else(|| key.span().before());
124 let prefix = RawString::with_span(prefix_span.start()..prefix_span.end());
125
126 let suffix_span = self
127 .current_suffix
128 .take()
129 .unwrap_or_else(|| key.span().after());
130 let suffix = RawString::with_span(suffix_span.start()..suffix_span.end());
131
132 let key_span = key.span();
133 let key_raw = RawString::with_span(key_span.start()..key_span.end());
134
135 let raw = source.get(key).unwrap();
136 let mut decoded = std::borrow::Cow::Borrowed("");
137 raw.decode_key(&mut decoded, errors);
138
139 let key = Key::new(decoded)
140 .with_repr_unchecked(Repr::new_unchecked(key_raw))
141 .with_dotted_decor(Decor::new(prefix, suffix));
142 if let Some(last_key) = result_key.replace(key) {
143 result_path.push(last_key);
144 }
145 }
146}
147
148pub(crate) fn on_simple_key(
153 event: &toml_parser::parser::Event,
154 source: toml_parser::Source<'_>,
155 errors: &mut dyn ErrorSink,
156) -> (RawString, String) {
157 #[cfg(feature = "debug")]
158 let _scope = TraceScope::new("key::on_simple_key");
159 let raw = source.get(event).unwrap();
160
161 let mut key = std::borrow::Cow::Borrowed("");
162 raw.decode_key(&mut key, errors);
163
164 let span = event.span();
165 let raw = RawString::with_span(span.start()..span.end());
166 let key = String::from(key);
167 (raw, key)
168}