1use std::{borrow::Cow, cell::Cell, io::Read, rc::Rc, str};
2
3use serde::Deserializer as _;
4use serde::de::{
5 self, DeserializeOwned, DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess,
6 Visitor,
7};
8use yaml_rt_core::{
9 NodeId, NonFiniteFloat, ResolvedScalar, SemanticKind, Span, YamlDoc, YamlScalarStyle,
10 resolve_scalar,
11};
12
13use crate::{Error, Result};
14
15const MAX_DEPTH: u8 = 128;
16
17struct Input<'de> {
18 doc: Option<YamlDoc>,
19 borrowed: Option<&'de str>,
20 error: Option<Error>,
21 semantic_len: usize,
22}
23
24impl<'de> Input<'de> {
25 fn parsed(text: String, borrowed: Option<&'de str>) -> Self {
26 match YamlDoc::parse_owned(text) {
27 Ok(doc) => {
28 let semantic_len = doc.events().count().max(1);
29 Self {
30 doc: Some(doc),
31 borrowed,
32 error: None,
33 semantic_len,
34 }
35 }
36 Err(error) => Self {
37 doc: None,
38 borrowed,
39 error: Some(error.into()),
40 semantic_len: 1,
41 },
42 }
43 }
44
45 fn failed(error: Error) -> Self {
46 Self {
47 doc: None,
48 borrowed: None,
49 error: Some(error),
50 semantic_len: 1,
51 }
52 }
53}
54
55pub struct Deserializer<'de> {
57 input: Rc<Input<'de>>,
58 selected: Option<usize>,
59 next_index: usize,
60 yielded_error: bool,
61}
62
63impl<'de> Deserializer<'de> {
64 #[must_use]
66 #[allow(clippy::should_implement_trait)]
67 pub fn from_str(input: &'de str) -> Self {
68 Self::new(Input::parsed(input.to_owned(), Some(input)))
69 }
70
71 #[must_use]
73 pub fn from_slice(input: &'de [u8]) -> Self {
74 match str::from_utf8(input) {
75 Ok(input) => Self::from_str(input),
76 Err(error) => Self::new(Input::failed(Error::message(error.to_string()))),
77 }
78 }
79
80 fn new(input: Input<'de>) -> Self {
81 Self {
82 input: Rc::new(input),
83 selected: None,
84 next_index: 0,
85 yielded_error: false,
86 }
87 }
88
89 fn node_deserializer(&self) -> Result<NodeDeserializer<'_, 'de>> {
90 if let Some(error) = &self.input.error {
91 return Err(error.clone());
92 }
93 let doc = self
94 .input
95 .doc
96 .as_ref()
97 .expect("parsed input has a document");
98 let index = if let Some(index) = self.selected {
99 index
100 } else {
101 match doc.document_count() {
102 0 => return Err(Error::message("EOF while parsing a value")),
103 1 => 0,
104 _ => {
105 return Err(Error::message(
106 "deserializing from YAML containing more than one document is not supported",
107 ));
108 }
109 }
110 };
111 let node = doc.document_root(index).map_err(Error::from)?;
112 Ok(NodeDeserializer {
113 input: &self.input,
114 node,
115 path: ".".to_owned(),
116 depth: MAX_DEPTH,
117 alias_jumps: Rc::new(Cell::new(0)),
118 ignore_tag: false,
119 })
120 }
121}
122
123impl Deserializer<'static> {
124 #[must_use]
126 pub fn from_reader<R>(mut reader: R) -> Self
127 where
128 R: Read,
129 {
130 let mut input = String::new();
131 match reader.read_to_string(&mut input) {
132 Ok(_) => Self::new(Input::parsed(input, None)),
133 Err(error) => Self::new(Input::failed(Error::io(error))),
134 }
135 }
136}
137
138impl<'de> Iterator for Deserializer<'de> {
139 type Item = Self;
140
141 fn next(&mut self) -> Option<Self::Item> {
142 if self.input.error.is_some() {
143 if self.yielded_error {
144 return None;
145 }
146 self.yielded_error = true;
147 return Some(Self {
148 input: Rc::clone(&self.input),
149 selected: Some(0),
150 next_index: 0,
151 yielded_error: true,
152 });
153 }
154 let count = self.input.doc.as_ref()?.document_count();
155 if self.next_index >= count {
156 return None;
157 }
158 let selected = self.next_index;
159 self.next_index += 1;
160 Some(Self {
161 input: Rc::clone(&self.input),
162 selected: Some(selected),
163 next_index: 0,
164 yielded_error: false,
165 })
166 }
167}
168
169pub fn from_str<'de, T>(input: &'de str) -> Result<T>
171where
172 T: serde::Deserialize<'de>,
173{
174 T::deserialize(Deserializer::from_str(input))
175}
176
177pub fn from_slice<'de, T>(input: &'de [u8]) -> Result<T>
179where
180 T: serde::Deserialize<'de>,
181{
182 T::deserialize(Deserializer::from_slice(input))
183}
184
185pub fn from_reader<R, T>(reader: R) -> Result<T>
187where
188 R: Read,
189 T: DeserializeOwned,
190{
191 T::deserialize(Deserializer::from_reader(reader))
192}
193
194macro_rules! delegate_deserializer {
195 ($($method:ident $(($($arg:ident : $ty:ty),*))?;)+) => {
196 $(
197 fn $method<V>(self, $($($arg: $ty,)*)? visitor: V) -> Result<V::Value>
198 where
199 V: Visitor<'de>,
200 {
201 self.node_deserializer()?.$method($($($arg,)*)? visitor)
202 }
203 )+
204 };
205}
206
207impl<'de> de::Deserializer<'de> for Deserializer<'de> {
208 type Error = Error;
209
210 delegate_deserializer! {
211 deserialize_any;
212 deserialize_bool;
213 deserialize_i8;
214 deserialize_i16;
215 deserialize_i32;
216 deserialize_i64;
217 deserialize_i128;
218 deserialize_u8;
219 deserialize_u16;
220 deserialize_u32;
221 deserialize_u64;
222 deserialize_u128;
223 deserialize_f32;
224 deserialize_f64;
225 deserialize_char;
226 deserialize_str;
227 deserialize_string;
228 deserialize_bytes;
229 deserialize_byte_buf;
230 deserialize_option;
231 deserialize_unit;
232 deserialize_unit_struct(name: &'static str);
233 deserialize_newtype_struct(name: &'static str);
234 deserialize_seq;
235 deserialize_tuple(len: usize);
236 deserialize_tuple_struct(name: &'static str, len: usize);
237 deserialize_map;
238 deserialize_struct(name: &'static str, fields: &'static [&'static str]);
239 deserialize_enum(name: &'static str, variants: &'static [&'static str]);
240 deserialize_identifier;
241 deserialize_ignored_any;
242 }
243
244 fn is_human_readable(&self) -> bool {
245 true
246 }
247}
248
249#[derive(Clone)]
250struct NodeDeserializer<'input, 'de> {
251 input: &'input Input<'de>,
252 node: Option<NodeId>,
253 path: String,
254 depth: u8,
255 alias_jumps: Rc<Cell<usize>>,
256 ignore_tag: bool,
257}
258
259impl<'input, 'de> NodeDeserializer<'input, 'de> {
260 fn doc(&self) -> &'input YamlDoc {
261 self.input.doc.as_ref().expect("node input is parsed")
262 }
263
264 fn span(&self) -> Span {
265 self.node
266 .and_then(|node| self.doc().node(node).map(|node| node.span()))
267 .unwrap_or_else(|| Span::empty(0))
268 }
269
270 fn annotate<T>(&self, result: Result<T>) -> Result<T> {
271 result.map_err(|error| error.at(self.doc(), self.span()).with_path(&self.path))
272 }
273
274 fn descend(&self, node: Option<NodeId>, path: String) -> Result<Self> {
275 let depth = self
276 .depth
277 .checked_sub(1)
278 .ok_or_else(|| Error::message("recursion limit exceeded"));
279 let depth = self.annotate(depth)?;
280 Ok(Self {
281 input: self.input,
282 node,
283 path,
284 depth,
285 alias_jumps: Rc::clone(&self.alias_jumps),
286 ignore_tag: false,
287 })
288 }
289
290 fn resolved(mut self) -> Result<Self> {
291 let mut seen = Vec::new();
292 while let Some(node) = self.node {
293 if !matches!(self.doc().semantic_kind(node), Some(SemanticKind::Alias)) {
294 break;
295 }
296 if seen.contains(&node) {
297 return self.annotate(Err(Error::message("recursive alias")));
298 }
299 seen.push(node);
300 let jumps = self.alias_jumps.get().saturating_add(1);
301 self.alias_jumps.set(jumps);
302 if jumps > self.input.semantic_len.saturating_mul(100) {
303 return self.annotate(Err(Error::message("alias repetition limit exceeded")));
304 }
305 let target = self.doc().resolve_alias(node).ok_or_else(|| {
306 Error::message(format!(
307 "unknown anchor `{}`",
308 self.doc().alias_name(node).unwrap_or_default()
309 ))
310 });
311 self.node = Some(self.annotate(target)?);
312 }
313 Ok(self)
314 }
315
316 fn child(&self, node: Option<NodeId>, path: String) -> Result<Self> {
317 self.descend(node, path)
318 }
319
320 fn scalar(&self) -> Result<(NodeId, Cow<'input, str>)> {
321 let node = self
322 .node
323 .ok_or_else(|| Error::message("expected a scalar, found null"));
324 let node = self.annotate(node)?;
325 if !matches!(
326 self.doc().semantic_kind(node),
327 Some(SemanticKind::Scalar { .. })
328 ) {
329 return self.annotate(Err(Error::message("expected a scalar value")));
330 }
331 let value = self
332 .doc()
333 .scalar_value(node)
334 .map(|value| (node, value))
335 .map_err(Error::from);
336 self.annotate(value)
337 }
338
339 fn custom_tag(&self) -> Option<String> {
340 if self.ignore_tag {
341 return None;
342 }
343 let raw = self.node.and_then(|node| self.doc().raw_tag(node))?;
344 if raw.starts_with("!!") || raw.starts_with("!<") || !raw.starts_with('!') {
345 return None;
346 }
347 let tag = raw.strip_prefix('!')?;
348 (!tag.is_empty()).then(|| tag.to_owned())
349 }
350
351 fn scalar_kind(&self) -> Result<ScalarKind> {
352 let Some(node) = self.node else {
353 return Ok(ScalarKind::Null);
354 };
355 let style = match self.doc().semantic_kind(node) {
356 Some(SemanticKind::Scalar { style }) => style,
357 _ => return Err(Error::message("expected a scalar value")),
358 };
359 let value = self.doc().scalar_value(node).map_err(Error::from)?;
360 let tag = self
361 .doc()
362 .resolved_tag(node)
363 .map_err(Error::from)?
364 .map(Cow::into_owned);
365 let resolved = resolve_scalar(&value, style, tag.as_deref())
366 .map_err(|error| Error::message(error.to_string()))?;
367 self.annotate(scalar_kind_from_resolved(resolved))
368 }
369
370 fn borrowed_scalar(&self, node: NodeId) -> Option<&'de str> {
371 let source = self.input.borrowed?;
372 let span = self.doc().borrowable_scalar_span(node).ok()??;
373 source.get(span.start as usize..span.end as usize)
374 }
375
376 fn is_empty_plain(&self) -> bool {
377 let Some(node) = self.node else {
378 return true;
379 };
380 matches!(
381 self.doc().semantic_kind(node),
382 Some(SemanticKind::Scalar {
383 style: YamlScalarStyle::Plain
384 })
385 ) && self
386 .doc()
387 .scalar_value(node)
388 .is_ok_and(|value| value.is_empty())
389 }
390}
391
392enum ScalarKind {
393 Null,
394 Bool(bool),
395 Signed(i128),
396 Unsigned(u128),
397 Float(f64),
398 String,
399}
400
401fn scalar_kind_from_resolved(value: ResolvedScalar) -> Result<ScalarKind> {
402 match value {
403 ResolvedScalar::Null => Ok(ScalarKind::Null),
404 ResolvedScalar::Bool(value) => Ok(ScalarKind::Bool(value)),
405 ResolvedScalar::Number(number) if number.has_integer_syntax() => {
406 if let Some(value) = number.as_i128()
407 && value < 0
408 {
409 Ok(ScalarKind::Signed(value))
410 } else if let Some(value) = number.as_u128() {
411 Ok(ScalarKind::Unsigned(value))
412 } else if let Some(value) = number.as_i128() {
413 Ok(ScalarKind::Signed(value))
414 } else {
415 Err(Error::message("integer is outside the supported range"))
416 }
417 }
418 ResolvedScalar::Number(number) => number
419 .as_f64()
420 .map(ScalarKind::Float)
421 .ok_or_else(|| Error::message("float is outside the supported range")),
422 ResolvedScalar::NonFinite(NonFiniteFloat::PositiveInfinity) => {
423 Ok(ScalarKind::Float(f64::INFINITY))
424 }
425 ResolvedScalar::NonFinite(NonFiniteFloat::NegativeInfinity) => {
426 Ok(ScalarKind::Float(f64::NEG_INFINITY))
427 }
428 ResolvedScalar::NonFinite(NonFiniteFloat::NaN) => Ok(ScalarKind::Float(f64::NAN)),
429 ResolvedScalar::String => Ok(ScalarKind::String),
430 }
431}
432
433impl<'de> de::Deserializer<'de> for NodeDeserializer<'_, 'de> {
434 type Error = Error;
435
436 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
437 where
438 V: Visitor<'de>,
439 {
440 let this = self.resolved()?;
441 if let Some(variant) = this.custom_tag() {
442 return visitor.visit_enum(YamlEnumAccess { de: this, variant });
443 }
444 let result = match this.node.and_then(|node| this.doc().semantic_kind(node)) {
445 None => visitor.visit_unit(),
446 Some(SemanticKind::Scalar { .. }) => match this.scalar_kind()? {
447 ScalarKind::Null => visitor.visit_unit(),
448 ScalarKind::Bool(value) => visitor.visit_bool(value),
449 ScalarKind::Signed(value) => visitor.visit_i128(value),
450 ScalarKind::Unsigned(value) => visitor.visit_u128(value),
451 ScalarKind::Float(value) => visitor.visit_f64(value),
452 ScalarKind::String => this.clone().deserialize_str(visitor),
453 },
454 Some(SemanticKind::Sequence { .. }) => this.clone().deserialize_seq(visitor),
455 Some(SemanticKind::Mapping { .. }) => this.clone().deserialize_map(visitor),
456 Some(SemanticKind::Alias) => unreachable!("aliases were resolved"),
457 Some(SemanticKind::Document) => Err(Error::message("unexpected document node")),
458 };
459 this.annotate(result)
460 }
461
462 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
463 where
464 V: Visitor<'de>,
465 {
466 let this = self.resolved()?;
467 let result = match this.scalar_kind()? {
468 ScalarKind::Bool(value) => visitor.visit_bool(value),
469 _ => Err(Error::message("expected a boolean")),
470 };
471 this.annotate(result)
472 }
473
474 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
475 where
476 V: Visitor<'de>,
477 {
478 deserialize_signed(self, visitor, |v| i8::try_from(v).ok(), Visitor::visit_i8)
479 }
480 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
481 where
482 V: Visitor<'de>,
483 {
484 deserialize_signed(self, visitor, |v| i16::try_from(v).ok(), Visitor::visit_i16)
485 }
486 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
487 where
488 V: Visitor<'de>,
489 {
490 deserialize_signed(self, visitor, |v| i32::try_from(v).ok(), Visitor::visit_i32)
491 }
492 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
493 where
494 V: Visitor<'de>,
495 {
496 deserialize_signed(self, visitor, |v| i64::try_from(v).ok(), Visitor::visit_i64)
497 }
498 fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
499 where
500 V: Visitor<'de>,
501 {
502 deserialize_signed(self, visitor, Some, Visitor::visit_i128)
503 }
504 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
505 where
506 V: Visitor<'de>,
507 {
508 deserialize_unsigned(self, visitor, |v| u8::try_from(v).ok(), Visitor::visit_u8)
509 }
510 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
511 where
512 V: Visitor<'de>,
513 {
514 deserialize_unsigned(self, visitor, |v| u16::try_from(v).ok(), Visitor::visit_u16)
515 }
516 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
517 where
518 V: Visitor<'de>,
519 {
520 deserialize_unsigned(self, visitor, |v| u32::try_from(v).ok(), Visitor::visit_u32)
521 }
522 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
523 where
524 V: Visitor<'de>,
525 {
526 deserialize_unsigned(self, visitor, |v| u64::try_from(v).ok(), Visitor::visit_u64)
527 }
528 fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
529 where
530 V: Visitor<'de>,
531 {
532 deserialize_unsigned(self, visitor, Some, Visitor::visit_u128)
533 }
534
535 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
536 where
537 V: Visitor<'de>,
538 {
539 deserialize_float(self, visitor, |visitor, value| {
540 visitor.visit_f32(value as f32)
541 })
542 }
543
544 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
545 where
546 V: Visitor<'de>,
547 {
548 deserialize_float(self, visitor, Visitor::visit_f64)
549 }
550
551 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
552 where
553 V: Visitor<'de>,
554 {
555 let this = self.resolved()?;
556 let (_, value) = this.scalar()?;
557 let mut chars = value.chars();
558 let value = chars
559 .next()
560 .filter(|_| chars.next().is_none())
561 .ok_or_else(|| Error::message("expected a single character"));
562 this.annotate(value.and_then(|value| visitor.visit_char(value)))
563 }
564
565 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
566 where
567 V: Visitor<'de>,
568 {
569 let this = self.resolved()?;
570 let (node, value) = this.scalar()?;
571 let result = if let Some(value) = this.borrowed_scalar(node) {
572 visitor.visit_borrowed_str(value)
573 } else {
574 match value {
575 Cow::Borrowed(value) => visitor.visit_str(value),
576 Cow::Owned(value) => visitor.visit_string(value),
577 }
578 };
579 this.annotate(result)
580 }
581
582 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
583 where
584 V: Visitor<'de>,
585 {
586 let this = self.resolved()?;
587 let (_, value) = this.scalar()?;
588 this.annotate(visitor.visit_string(value.into_owned()))
589 }
590
591 fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
592 where
593 V: Visitor<'de>,
594 {
595 Err(Error::message(
596 "serialization and deserialization of bytes in YAML is not implemented",
597 ))
598 }
599
600 fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
601 where
602 V: Visitor<'de>,
603 {
604 Err(Error::message(
605 "serialization and deserialization of bytes in YAML is not implemented",
606 ))
607 }
608
609 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
610 where
611 V: Visitor<'de>,
612 {
613 let this = self.resolved()?;
614 if matches!(this.scalar_kind(), Ok(ScalarKind::Null)) {
615 this.annotate(visitor.visit_none())
616 } else {
617 visitor.visit_some(this)
618 }
619 }
620
621 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
622 where
623 V: Visitor<'de>,
624 {
625 let this = self.resolved()?;
626 let result = if matches!(this.scalar_kind(), Ok(ScalarKind::Null)) {
627 visitor.visit_unit()
628 } else {
629 Err(Error::message("expected null"))
630 };
631 this.annotate(result)
632 }
633
634 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
635 where
636 V: Visitor<'de>,
637 {
638 self.deserialize_unit(visitor)
639 }
640
641 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
642 where
643 V: Visitor<'de>,
644 {
645 visitor.visit_newtype_struct(self)
646 }
647
648 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
649 where
650 V: Visitor<'de>,
651 {
652 let this = self.resolved()?;
653 if this.is_empty_plain() {
654 return this.annotate(visitor.visit_seq(EmptyAccess));
655 }
656 let node = this
657 .node
658 .ok_or_else(|| Error::message("expected a sequence"))?;
659 if !matches!(
660 this.doc().semantic_kind(node),
661 Some(SemanticKind::Sequence { .. })
662 ) {
663 return this.annotate(Err(Error::message("expected a sequence")));
664 }
665 let items = this.doc().sequence_items(node).collect::<Vec<_>>();
666 let context = this.clone();
667 context.annotate(visitor.visit_seq(YamlSeqAccess {
668 de: this,
669 items,
670 index: 0,
671 }))
672 }
673
674 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
675 where
676 V: Visitor<'de>,
677 {
678 self.deserialize_seq(visitor)
679 }
680
681 fn deserialize_tuple_struct<V>(
682 self,
683 _name: &'static str,
684 _len: usize,
685 visitor: V,
686 ) -> Result<V::Value>
687 where
688 V: Visitor<'de>,
689 {
690 self.deserialize_seq(visitor)
691 }
692
693 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
694 where
695 V: Visitor<'de>,
696 {
697 let this = self.resolved()?;
698 if this.is_empty_plain() {
699 return this.annotate(visitor.visit_map(EmptyAccess));
700 }
701 let node = this
702 .node
703 .ok_or_else(|| Error::message("expected a mapping"))?;
704 if !matches!(
705 this.doc().semantic_kind(node),
706 Some(SemanticKind::Mapping { .. })
707 ) {
708 return this.annotate(Err(Error::message("expected a mapping")));
709 }
710 let entries = this.doc().mapping_entries(node).collect::<Vec<_>>();
711 let context = this.clone();
712 context.annotate(visitor.visit_map(YamlMapAccess {
713 de: this,
714 entries,
715 index: 0,
716 pending: None,
717 }))
718 }
719
720 fn deserialize_struct<V>(
721 self,
722 _name: &'static str,
723 _fields: &'static [&'static str],
724 visitor: V,
725 ) -> Result<V::Value>
726 where
727 V: Visitor<'de>,
728 {
729 self.deserialize_map(visitor)
730 }
731
732 fn deserialize_enum<V>(
733 self,
734 _name: &'static str,
735 _variants: &'static [&'static str],
736 visitor: V,
737 ) -> Result<V::Value>
738 where
739 V: Visitor<'de>,
740 {
741 let this = self.resolved()?;
742 let variant = if let Some(variant) = this.custom_tag() {
743 variant
744 } else {
745 let (_, value) = this.scalar()?;
746 value.into_owned()
747 };
748 let context = this.clone();
749 context.annotate(visitor.visit_enum(YamlEnumAccess { de: this, variant }))
750 }
751
752 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
753 where
754 V: Visitor<'de>,
755 {
756 self.deserialize_str(visitor)
757 }
758
759 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
760 where
761 V: Visitor<'de>,
762 {
763 visitor.visit_unit()
764 }
765
766 fn is_human_readable(&self) -> bool {
767 true
768 }
769}
770
771fn signed_value(kind: ScalarKind) -> Option<i128> {
772 match kind {
773 ScalarKind::Signed(value) => Some(value),
774 ScalarKind::Unsigned(value) => i128::try_from(value).ok(),
775 _ => None,
776 }
777}
778
779fn unsigned_value(kind: ScalarKind) -> Option<u128> {
780 match kind {
781 ScalarKind::Unsigned(value) => Some(value),
782 ScalarKind::Signed(value) => u128::try_from(value).ok(),
783 _ => None,
784 }
785}
786
787fn deserialize_signed<'de, V, T>(
788 de: NodeDeserializer<'_, 'de>,
789 visitor: V,
790 convert: impl FnOnce(i128) -> Option<T>,
791 visit: impl FnOnce(V, T) -> Result<V::Value>,
792) -> Result<V::Value>
793where
794 V: Visitor<'de>,
795{
796 let de = de.resolved()?;
797 let value = signed_value(de.scalar_kind()?)
798 .and_then(convert)
799 .ok_or_else(|| Error::message("expected an integer in range"));
800 de.annotate(value.and_then(|value| visit(visitor, value)))
801}
802
803fn deserialize_unsigned<'de, V, T>(
804 de: NodeDeserializer<'_, 'de>,
805 visitor: V,
806 convert: impl FnOnce(u128) -> Option<T>,
807 visit: impl FnOnce(V, T) -> Result<V::Value>,
808) -> Result<V::Value>
809where
810 V: Visitor<'de>,
811{
812 let de = de.resolved()?;
813 let value = unsigned_value(de.scalar_kind()?)
814 .and_then(convert)
815 .ok_or_else(|| Error::message("expected an unsigned integer in range"));
816 de.annotate(value.and_then(|value| visit(visitor, value)))
817}
818
819fn deserialize_float<'de, V>(
820 de: NodeDeserializer<'_, 'de>,
821 visitor: V,
822 visit: impl FnOnce(V, f64) -> Result<V::Value>,
823) -> Result<V::Value>
824where
825 V: Visitor<'de>,
826{
827 let de = de.resolved()?;
828 let value = match de.scalar_kind()? {
829 ScalarKind::Float(value) => Some(value),
830 ScalarKind::Signed(value) => Some(value as f64),
831 ScalarKind::Unsigned(value) => Some(value as f64),
832 _ => None,
833 }
834 .ok_or_else(|| Error::message("expected a number"));
835 de.annotate(value.and_then(|value| visit(visitor, value)))
836}
837
838struct EmptyAccess;
839
840impl<'de> SeqAccess<'de> for EmptyAccess {
841 type Error = Error;
842 fn next_element_seed<T>(&mut self, _seed: T) -> Result<Option<T::Value>>
843 where
844 T: DeserializeSeed<'de>,
845 {
846 Ok(None)
847 }
848}
849
850impl<'de> MapAccess<'de> for EmptyAccess {
851 type Error = Error;
852 fn next_key_seed<K>(&mut self, _seed: K) -> Result<Option<K::Value>>
853 where
854 K: DeserializeSeed<'de>,
855 {
856 Ok(None)
857 }
858 fn next_value_seed<V>(&mut self, _seed: V) -> Result<V::Value>
859 where
860 V: DeserializeSeed<'de>,
861 {
862 Err(Error::message("value requested without a key"))
863 }
864}
865
866struct YamlSeqAccess<'input, 'de> {
867 de: NodeDeserializer<'input, 'de>,
868 items: Vec<NodeId>,
869 index: usize,
870}
871
872impl<'de> SeqAccess<'de> for YamlSeqAccess<'_, 'de> {
873 type Error = Error;
874 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
875 where
876 T: DeserializeSeed<'de>,
877 {
878 let Some(node) = self.items.get(self.index).copied() else {
879 return Ok(None);
880 };
881 let index = self.index;
882 self.index += 1;
883 let child = self
884 .de
885 .child(Some(node), format!("{}[{index}]", self.de.path))?;
886 seed.deserialize(child).map(Some)
887 }
888 fn size_hint(&self) -> Option<usize> {
889 Some(self.items.len().saturating_sub(self.index))
890 }
891}
892
893struct YamlMapAccess<'input, 'de> {
894 de: NodeDeserializer<'input, 'de>,
895 entries: Vec<(NodeId, NodeId)>,
896 index: usize,
897 pending: Option<(NodeId, String)>,
898}
899
900impl<'de> MapAccess<'de> for YamlMapAccess<'_, 'de> {
901 type Error = Error;
902 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
903 where
904 K: DeserializeSeed<'de>,
905 {
906 let Some((key, value)) = self.entries.get(self.index).copied() else {
907 return Ok(None);
908 };
909 self.index += 1;
910 let key_name = self
911 .de
912 .doc()
913 .scalar_value(key)
914 .ok()
915 .map_or_else(|| "?".to_owned(), Cow::into_owned);
916 let path = if key_name
917 .chars()
918 .all(|c| c.is_alphanumeric() || c == '_' || c == '-')
919 {
920 format!("{}.{}", self.de.path.trim_end_matches('.'), key_name)
921 } else {
922 format!("{}[{:?}]", self.de.path, key_name)
923 };
924 self.pending = Some((value, path));
925 let child = self
926 .de
927 .child(Some(key), format!("{}.<key>", self.de.path))?;
928 seed.deserialize(child).map(Some)
929 }
930 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
931 where
932 V: DeserializeSeed<'de>,
933 {
934 let (node, path) = self
935 .pending
936 .take()
937 .ok_or_else(|| Error::message("value requested without a key"))?;
938 seed.deserialize(self.de.child(Some(node), path)?)
939 }
940 fn size_hint(&self) -> Option<usize> {
941 Some(self.entries.len().saturating_sub(self.index))
942 }
943}
944
945struct YamlEnumAccess<'input, 'de> {
946 de: NodeDeserializer<'input, 'de>,
947 variant: String,
948}
949
950impl<'input, 'de> EnumAccess<'de> for YamlEnumAccess<'input, 'de> {
951 type Error = Error;
952 type Variant = YamlVariantAccess<'input, 'de>;
953 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
954 where
955 V: DeserializeSeed<'de>,
956 {
957 let variant = seed.deserialize(serde::de::value::StrDeserializer::<Error>::new(
958 self.variant.as_str(),
959 ))?;
960 Ok((variant, YamlVariantAccess { de: self.de }))
961 }
962}
963
964struct YamlVariantAccess<'input, 'de> {
965 de: NodeDeserializer<'input, 'de>,
966}
967
968impl<'de> VariantAccess<'de> for YamlVariantAccess<'_, 'de> {
969 type Error = Error;
970 fn unit_variant(self) -> Result<()> {
971 Ok(())
972 }
973 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
974 where
975 T: DeserializeSeed<'de>,
976 {
977 let mut de = self.de;
978 de.ignore_tag = true;
979 seed.deserialize(de)
980 }
981 fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
982 where
983 V: Visitor<'de>,
984 {
985 let mut de = self.de;
986 de.ignore_tag = true;
987 de.deserialize_tuple(len, visitor)
988 }
989 fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
990 where
991 V: Visitor<'de>,
992 {
993 let mut de = self.de;
994 de.ignore_tag = true;
995 de.deserialize_struct("", fields, visitor)
996 }
997}