1extern crate alloc;
7
8use alloc::{borrow::Cow, format, vec::Vec};
9
10use facet_format::{
11 ContainerKind, DeserializeErrorKind, FieldKey, FieldLocationHint, FormatParser, ParseError,
12 ParseEvent, ParseEventKind, SavePoint, ScalarValue,
13};
14use facet_reflect::Span;
15use saphyr_parser::{Event, Parser, ScalarStyle, Span as SaphyrSpan, StrInput};
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23enum ContextState {
24 MappingKey,
26 MappingValue,
28 SequenceValue,
30}
31
32pub struct YamlParser<'de> {
41 input: &'de str,
43 parser: Parser<'de, StrInput<'de>>,
45 stack: Vec<ContextState>,
47 event_peek: Option<ParseEvent<'de>>,
49 started: bool,
51 last_span: Span,
53 save_counter: u64,
55 recording: Option<Vec<ParseEvent<'de>>>,
57 replay_buffer: Vec<ParseEvent<'de>>,
59}
60
61fn span_from_saphyr(span: &SaphyrSpan) -> Span {
63 let start = span.start.index();
64 let end = span.end.index();
65 Span::new(start, end.saturating_sub(start))
66}
67
68impl<'de> YamlParser<'de> {
69 pub fn new(input: &'de str) -> Self {
71 Self {
72 input,
73 parser: Parser::new_from_str(input),
74 stack: Vec::new(),
75 event_peek: None,
76 started: false,
77 last_span: Span::new(0, 0),
78 save_counter: 0,
79 recording: None,
80 replay_buffer: Vec::new(),
81 }
82 }
83
84 pub const fn input(&self) -> &'de str {
86 self.input
87 }
88
89 fn next_raw_event(&mut self) -> Result<Option<(Event<'de>, SaphyrSpan)>, ParseError> {
91 match self.parser.next_event() {
92 Some(Ok((event, span))) => {
93 self.last_span = span_from_saphyr(&span);
94 Ok(Some((event, span)))
95 }
96 Some(Err(e)) => {
97 let span = Span::new(e.marker().index(), 1);
99 Err(ParseError::new(
100 span,
101 DeserializeErrorKind::InvalidValue {
102 message: format!("{e}").into(),
103 },
104 ))
105 }
106 None => Ok(None),
107 }
108 }
109
110 fn skip_preamble(&mut self) -> Result<(), ParseError> {
112 if self.started {
113 return Ok(());
114 }
115 self.started = true;
116
117 if let Some((Event::StreamStart, _)) = self.next_raw_event()? {
119 }
121
122 if let Some(Ok((Event::DocumentStart(_), _))) = self.parser.peek() {
125 self.next_raw_event()?;
126 }
127
128 Ok(())
129 }
130
131 fn produce_event(&mut self) -> Result<Option<ParseEvent<'de>>, ParseError> {
133 self.skip_preamble()?;
134
135 let (event, _span) = match self.next_raw_event()? {
136 Some(ev) => ev,
137 None => return Ok(None),
138 };
139
140 match event {
141 Event::StreamStart | Event::DocumentStart(_) => {
142 self.produce_event()
144 }
145 Event::StreamEnd | Event::DocumentEnd => {
146 Ok(None)
148 }
149 Event::MappingStart(_anchor, _tag) => {
150 self.stack.push(ContextState::MappingKey);
151 Ok(Some(
152 self.event(ParseEventKind::StructStart(ContainerKind::Object)),
153 ))
154 }
155 Event::MappingEnd => {
156 self.stack.pop();
157 if let Some(ctx @ ContextState::MappingValue) = self.stack.last_mut() {
159 *ctx = ContextState::MappingKey;
160 }
161 Ok(Some(self.event(ParseEventKind::StructEnd)))
162 }
163 Event::SequenceStart(_anchor, _tag) => {
164 self.stack.push(ContextState::SequenceValue);
165 Ok(Some(self.event(ParseEventKind::SequenceStart(
166 ContainerKind::Array,
167 ))))
168 }
169 Event::SequenceEnd => {
170 self.stack.pop();
171 if let Some(ctx @ ContextState::MappingValue) = self.stack.last_mut() {
173 *ctx = ContextState::MappingKey;
174 }
175 Ok(Some(self.event(ParseEventKind::SequenceEnd)))
176 }
177 Event::Scalar(value, style, _anchor, _tag) => {
178 if let Some(ctx @ ContextState::MappingKey) = self.stack.last_mut() {
180 *ctx = ContextState::MappingValue;
182 Ok(Some(self.event(ParseEventKind::FieldKey(FieldKey::new(
183 value,
184 FieldLocationHint::KeyValue,
185 )))))
186 } else {
187 if let Some(ctx @ ContextState::MappingValue) = self.stack.last_mut() {
189 *ctx = ContextState::MappingKey;
190 }
191 Ok(Some(self.event(ParseEventKind::Scalar(
192 self.scalar_to_value(value, style),
193 ))))
194 }
195 }
196 Event::Alias(_id) => {
197 if let Some(ctx @ ContextState::MappingValue) = self.stack.last_mut() {
199 *ctx = ContextState::MappingKey;
200 }
201 Ok(Some(self.event(ParseEventKind::Scalar(ScalarValue::Null))))
202 }
203 Event::Nothing => {
204 self.produce_event()
206 }
207 }
208 }
209
210 fn scalar_to_value(&self, value: Cow<'de, str>, style: ScalarStyle) -> ScalarValue<'de> {
212 if matches!(style, ScalarStyle::SingleQuoted | ScalarStyle::DoubleQuoted) {
214 return ScalarValue::Str(value);
215 }
216
217 if is_yaml_null(&value) {
219 return ScalarValue::Null;
220 }
221
222 if let Some(b) = parse_yaml_bool(&value) {
224 return ScalarValue::Bool(b);
225 }
226
227 if let Ok(n) = value.parse::<i64>() {
229 return ScalarValue::I64(n);
230 }
231 if let Ok(n) = value.parse::<u64>() {
232 return ScalarValue::U64(n);
233 }
234
235 if let Ok(f) = value.parse::<f64>() {
237 return ScalarValue::F64(f);
238 }
239
240 match value.as_ref() {
242 ".inf" | ".Inf" | ".INF" => return ScalarValue::F64(f64::INFINITY),
243 "-.inf" | "-.Inf" | "-.INF" => return ScalarValue::F64(f64::NEG_INFINITY),
244 ".nan" | ".NaN" | ".NAN" => return ScalarValue::F64(f64::NAN),
245 _ => {}
246 }
247
248 ScalarValue::Str(value)
250 }
251
252 fn skip_current_value(&mut self) -> Result<(), ParseError> {
255 let mut depth = 0i32;
256
257 loop {
258 let event = self.next_event_internal()?;
259 match event.as_ref().map(|e| &e.kind) {
260 Some(ParseEventKind::StructStart(_) | ParseEventKind::SequenceStart(_)) => {
261 depth += 1;
262 }
263 Some(ParseEventKind::StructEnd | ParseEventKind::SequenceEnd) => {
264 depth -= 1;
265 if depth <= 0 {
266 return Ok(());
267 }
268 }
269 Some(ParseEventKind::Scalar(_)) if depth == 0 => {
270 return Ok(());
271 }
272 Some(_) => {}
273 None => return Ok(()),
274 }
275 }
276 }
277
278 fn next_event_internal(&mut self) -> Result<Option<ParseEvent<'de>>, ParseError> {
280 if let Some(event) = self.replay_buffer.pop() {
282 return Ok(Some(event));
283 }
284
285 if let Some(event) = self.event_peek.take() {
287 if let Some(ref mut rec) = self.recording {
289 rec.push(event.clone());
290 }
291 return Ok(Some(event));
292 }
293
294 let event = self.produce_event()?;
296 if let Some(ref mut rec) = self.recording
298 && let Some(ref e) = event
299 {
300 rec.push(e.clone());
301 }
302 Ok(event)
303 }
304}
305
306impl<'de> FormatParser<'de> for YamlParser<'de> {
307 fn next_event(&mut self) -> Result<Option<ParseEvent<'de>>, ParseError> {
308 self.next_event_internal()
309 }
310
311 fn peek_event(&mut self) -> Result<Option<ParseEvent<'de>>, ParseError> {
312 if let Some(event) = self.replay_buffer.last().cloned() {
314 return Ok(Some(event));
315 }
316 if let Some(event) = self.event_peek.clone() {
318 return Ok(Some(event));
319 }
320 let event = self.produce_event()?;
322 if let Some(ref e) = event {
323 self.event_peek = Some(e.clone());
324 }
325 Ok(event)
326 }
327
328 fn skip_value(&mut self) -> Result<(), ParseError> {
329 debug_assert!(
330 self.event_peek.is_none(),
331 "skip_value called while an event is buffered"
332 );
333 self.skip_current_value()
334 }
335
336 fn save(&mut self) -> SavePoint {
337 self.save_counter += 1;
338 self.recording = Some(Vec::new());
339 SavePoint(self.save_counter)
340 }
341
342 fn restore(&mut self, _save_point: SavePoint) {
343 if let Some(mut recorded) = self.recording.take() {
344 recorded.reverse();
346 recorded.append(&mut self.replay_buffer);
348 self.replay_buffer = recorded;
349 }
350 }
351
352 fn capture_raw(&mut self) -> Result<Option<&'de str>, ParseError> {
353 self.skip_value()?;
355 Ok(None)
356 }
357
358 fn current_span(&self) -> Option<Span> {
359 Some(self.last_span)
360 }
361}
362
363impl<'de> YamlParser<'de> {
364 #[inline]
366 fn event(&self, kind: ParseEventKind<'de>) -> ParseEvent<'de> {
367 ParseEvent::new(kind, self.last_span)
368 }
369}
370
371fn is_yaml_null(value: &str) -> bool {
377 matches!(
378 value.to_lowercase().as_str(),
379 "null" | "~" | "" | "nil" | "none"
380 )
381}
382
383fn parse_yaml_bool(value: &str) -> Option<bool> {
385 match value.to_lowercase().as_str() {
386 "true" | "yes" | "on" | "y" => Some(true),
387 "false" | "no" | "off" | "n" => Some(false),
388 _ => None,
389 }
390}