1use serde_spanned::Spanned;
2
3use crate::alloc_prelude::*;
4use crate::de::parser::prelude::*;
5use crate::de::DeString;
6
7pub(crate) fn on_key<'i>(
12 key_event: &toml_parser::parser::Event,
13 input: &mut Input<'_>,
14 source: toml_parser::Source<'i>,
15 errors: &mut dyn ErrorSink,
16) -> (Vec<Spanned<DeString<'i>>>, Option<Spanned<DeString<'i>>>) {
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_key: Option<toml_parser::parser::Event>,
89}
90
91impl State {
92 fn new(key_event: &toml_parser::parser::Event) -> Self {
93 Self {
94 current_key: Some(*key_event),
95 }
96 }
97
98 fn whitespace(&mut self, _event: &toml_parser::parser::Event) {}
99
100 fn close_key<'i>(
101 &mut self,
102 result_path: &mut Vec<Spanned<DeString<'i>>>,
103 result_key: &mut Option<Spanned<DeString<'i>>>,
104 source: toml_parser::Source<'i>,
105 errors: &mut dyn ErrorSink,
106 ) {
107 let Some(key) = self.current_key.take() else {
108 return;
109 };
110
111 let key_span = key.span();
112 let key_span = key_span.start()..key_span.end();
113
114 let raw = source.get(key).unwrap();
115 let mut decoded = alloc::borrow::Cow::Borrowed("");
116 raw.decode_key(&mut decoded, errors);
117
118 let key = Spanned::new(key_span, decoded);
119 if let Some(last_key) = result_key.replace(key) {
120 result_path.push(last_key);
121 }
122 }
123}