serde_path_to_error/
path.rs1use super::Chain;
2use alloc::borrow::ToOwned as _;
3use alloc::string::String;
4use alloc::vec::Vec;
5use core::fmt::{self, Display};
6use core::slice;
7
8#[derive(Clone, Debug)]
14pub struct Path {
15 segments: Vec<Segment>,
16}
17
18#[derive(Clone, Debug)]
20pub enum Segment {
21 Seq { index: usize },
22 Map { key: String },
23 Enum { variant: String },
24 Unknown,
25}
26
27impl Path {
28 pub fn iter(&self) -> Segments {
30 Segments {
31 iter: self.segments.iter(),
32 }
33 }
34}
35
36impl<'a> IntoIterator for &'a Path {
37 type Item = &'a Segment;
38 type IntoIter = Segments<'a>;
39
40 fn into_iter(self) -> Self::IntoIter {
41 self.iter()
42 }
43}
44
45pub struct Segments<'a> {
47 iter: slice::Iter<'a, Segment>,
48}
49
50impl<'a> Iterator for Segments<'a> {
51 type Item = &'a Segment;
52
53 fn next(&mut self) -> Option<Self::Item> {
54 self.iter.next()
55 }
56
57 fn size_hint(&self) -> (usize, Option<usize>) {
58 self.iter.size_hint()
59 }
60}
61
62impl<'a> DoubleEndedIterator for Segments<'a> {
63 fn next_back(&mut self) -> Option<Self::Item> {
64 self.iter.next_back()
65 }
66}
67
68impl<'a> ExactSizeIterator for Segments<'a> {
69 fn len(&self) -> usize {
70 self.iter.len()
71 }
72}
73
74impl Display for Path {
75 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
76 if self.segments.is_empty() {
77 return formatter.write_str(".");
78 }
79
80 let mut separator = "";
81 for segment in self {
82 if !matches!(segment, Segment::Seq { .. }) {
83 formatter.write_str(separator)?;
84 }
85 write!(formatter, "{}", segment)?;
86 separator = ".";
87 }
88
89 Ok(())
90 }
91}
92
93impl Path {
94 pub(crate) fn empty() -> Self {
95 Path {
96 segments: Vec::new(),
97 }
98 }
99
100 pub(crate) fn from_chain(mut chain: &Chain) -> Self {
101 let mut segments = Vec::new();
102 loop {
103 match chain {
104 Chain::Root => break,
105 Chain::Seq { parent, index } => {
106 segments.push(Segment::Seq { index: *index });
107 chain = parent;
108 }
109 Chain::Map { parent, key } => {
110 segments.push(Segment::Map { key: key.clone() });
111 chain = parent;
112 }
113 Chain::Struct { parent, key } => {
114 let key = *key;
115 segments.push(Segment::Map {
116 key: key.to_owned(),
117 });
118 chain = parent;
119 }
120 Chain::Enum { parent, variant } => {
121 segments.push(Segment::Enum {
122 variant: variant.clone(),
123 });
124 chain = parent;
125 }
126 Chain::Some { parent }
127 | Chain::NewtypeStruct { parent }
128 | Chain::NewtypeVariant { parent } => {
129 chain = parent;
130 }
131 Chain::NonStringKey { parent } => {
132 segments.push(Segment::Unknown);
133 chain = parent;
134 }
135 }
136 }
137 segments.reverse();
138 Path { segments }
139 }
140
141 pub(crate) fn is_only_unknown(&self) -> bool {
142 self.segments.iter().all(Segment::is_unknown)
143 }
144}
145
146impl Display for Segment {
147 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
148 match self {
149 Segment::Seq { index } => write!(formatter, "[{}]", index),
150 Segment::Map { key } | Segment::Enum { variant: key } => {
151 write!(formatter, "{}", key)
152 }
153 Segment::Unknown => formatter.write_str("?"),
154 }
155 }
156}
157
158impl Segment {
159 fn is_unknown(&self) -> bool {
160 matches!(self, Segment::Unknown)
161 }
162}