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