1use std::borrow::Cow;
2use std::fmt::{self, Write as _};
3
4use regex::RegexSet;
5use serde::de;
6
7pub trait Callback<'a> {
8 fn on_match(&mut self, matched: &str) -> bool;
9 fn on_finish(&mut self) -> bool {
10 false
11 }
12
13 fn push_index(&mut self) {}
14 fn bump_index(&mut self) {}
15 fn pop_index(&mut self) {}
16
17 fn push_key(&mut self) {}
18 fn set_key(&mut self, _key: Cow<'a, str>) {}
19 fn pop_key(&mut self) {}
20}
21
22impl<'a, C1: Callback<'a>, C2: Callback<'a>> Callback<'a> for (C1, C2) {
23 fn on_match(&mut self, matched: &str) -> bool {
24 self.0.on_match(matched) || self.1.on_match(matched)
25 }
26
27 fn on_finish(&mut self) -> bool {
28 self.0.on_finish() || self.1.on_finish()
29 }
30
31 fn push_index(&mut self) {
32 self.0.push_index();
33 self.1.push_index();
34 }
35
36 fn bump_index(&mut self) {
37 self.0.bump_index();
38 self.1.bump_index();
39 }
40
41 fn pop_index(&mut self) {
42 self.0.pop_index();
43 self.1.pop_index();
44 }
45
46 fn push_key(&mut self) {
47 self.0.push_key();
48 self.1.push_key();
49 }
50
51 fn set_key(&mut self, key: Cow<'a, str>) {
52 self.0.set_key(key.clone());
53 self.1.set_key(key);
54 }
55
56 fn pop_key(&mut self) {
57 self.0.pop_key();
58 self.1.pop_key();
59 }
60}
61
62pub trait PathCallback<'a> {
63 fn path(&mut self) -> &mut Path<'a>;
64 fn on_match(&mut self, matched: &str) -> bool;
65 fn on_finish(&mut self) -> bool {
66 false
67 }
68}
69
70impl<'a, C: PathCallback<'a>> Callback<'a> for C {
71 fn on_match(&mut self, matched: &str) -> bool {
72 PathCallback::on_match(self, matched)
73 }
74
75 fn on_finish(&mut self) -> bool {
76 PathCallback::on_finish(self)
77 }
78
79 fn push_index(&mut self) {
80 self.path().push_index();
81 }
82
83 fn bump_index(&mut self) {
84 self.path().bump_index();
85 }
86
87 fn pop_index(&mut self) {
88 self.path().pop();
89 }
90
91 fn push_key(&mut self) {
92 self.path().push_key();
93 }
94
95 fn set_key(&mut self, key: Cow<'a, str>) {
96 self.path().set_key(key);
97 }
98
99 fn pop_key(&mut self) {
100 self.path().pop();
101 }
102}
103
104#[derive(Clone, Debug, Default, Eq, PartialEq)]
105pub struct Path<'a>(Vec<PathSegment<'a>>);
106
107impl<'a> Path<'a> {
108 fn push_index(&mut self) {
109 self.0.push(PathSegment::Index(0));
110 }
111
112 fn bump_index(&mut self) {
113 match self.0.last_mut() {
114 Some(PathSegment::Index(index)) => *index += 1,
115 _ => unreachable!(),
116 }
117 }
118
119 fn push_key(&mut self) {
120 self.0.push(PathSegment::Key(Cow::Borrowed("")));
121 }
122
123 fn set_key(&mut self, value: Cow<'a, str>) {
124 match self.0.last_mut() {
125 Some(PathSegment::Key(key)) => *key = value,
126 _ => unreachable!(),
127 }
128 }
129
130 fn pop(&mut self) {
131 self.0.pop();
132 }
133}
134
135impl fmt::Display for Path<'_> {
136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137 f.write_char('$')?;
138 self.0.iter().try_for_each(|segment| write!(f, "{segment}"))
139 }
140}
141
142#[derive(Clone, Debug, Eq, PartialEq)]
143pub enum PathSegment<'a> {
144 Index(usize),
145 Key(Cow<'a, str>),
146}
147
148impl fmt::Display for PathSegment<'_> {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 match self {
151 Self::Index(index) => write!(f, "[{index}]"),
152 Self::Key(key) => write!(f, "['{}']", JsonPathNormalisedName(key)),
153 }
154 }
155}
156
157struct JsonPathNormalisedName<'a>(&'a str);
158
159impl fmt::Display for JsonPathNormalisedName<'_> {
160 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 for c in self.0.chars() {
162 match c {
163 '\\' => f.write_str("\\\\")?,
164 '\'' => f.write_str("\\'")?,
165 '\x08' => f.write_str("\\b")?,
166 '\t' => f.write_str("\\t")?,
167 '\n' => f.write_str("\\n")?,
168 '\x0C' => f.write_str("\\f")?,
169 '\r' => f.write_str("\\r")?,
170 '\0'..' ' => write!(f, "\\u{:04x}", c as u32)?,
171 _ => f.write_char(c)?,
172 }
173 }
174 Ok(())
175 }
176}
177
178pub struct Walker<'b, C: ?Sized> {
179 patterns: RegexSet,
180 invert: bool,
181 callback: &'b mut C,
182}
183
184impl<'a, 'b, C: Callback<'a> + ?Sized> Walker<'b, C> {
185 pub fn new(patterns: RegexSet, invert: bool, callback: &'b mut C) -> Self {
186 Self {
187 patterns,
188 invert,
189 callback,
190 }
191 }
192
193 fn seq_loop<'de: 'a, A: de::SeqAccess<'de>>(&mut self, mut seq: A) -> Result<bool, A::Error> {
194 while let Some(stop) = seq.next_element_seed(&mut *self)? {
195 if stop {
196 return Self::drain_seq(seq);
197 }
198 self.callback.bump_index();
199 }
200 Ok(false)
201 }
202
203 fn map_loop<'de: 'a, A: de::MapAccess<'de>>(&mut self, mut map: A) -> Result<bool, A::Error> {
204 while let Some(key) = map.next_key_seed(MapKeyVisitor)? {
205 self.callback.set_key(key);
206 if map.next_value_seed(&mut *self)? {
207 return Self::drain_map(map);
208 }
209 }
210 Ok(false)
211 }
212
213 fn drain_seq<'de: 'a, A: de::SeqAccess<'de>>(mut seq: A) -> Result<bool, A::Error> {
214 while let Some(de::IgnoredAny) = seq.next_element()? {}
215 Ok(true)
216 }
217
218 fn drain_map<'de: 'a, A: de::MapAccess<'de>>(mut map: A) -> Result<bool, A::Error> {
219 while let Some((de::IgnoredAny, de::IgnoredAny)) = map.next_entry()? {}
220 Ok(true)
221 }
222}
223
224impl<'de: 'a, 'a, C: Callback<'a> + ?Sized> de::DeserializeSeed<'de> for &mut Walker<'_, C> {
225 type Value = bool;
226
227 fn deserialize<D: de::Deserializer<'de>>(
228 self,
229 deserializer: D,
230 ) -> Result<Self::Value, D::Error> {
231 deserializer.deserialize_any(self)
232 }
233}
234
235impl<'de: 'a, 'a, C: Callback<'a> + ?Sized> de::Visitor<'de> for &mut Walker<'_, C> {
236 type Value = bool;
237
238 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
239 write!(formatter, "a JSON value")
240 }
241
242 fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
243 Ok(false)
244 }
245
246 fn visit_bool<E: de::Error>(self, _v: bool) -> Result<Self::Value, E> {
247 Ok(false)
248 }
249
250 fn visit_u64<E: de::Error>(self, _v: u64) -> Result<Self::Value, E> {
251 Ok(false)
252 }
253
254 fn visit_i64<E: de::Error>(self, _v: i64) -> Result<Self::Value, E> {
255 Ok(false)
256 }
257
258 fn visit_f64<E: de::Error>(self, _v: f64) -> Result<Self::Value, E> {
259 Ok(false)
260 }
261
262 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
263 Ok(self.patterns.is_match(v) != self.invert && self.callback.on_match(v))
264 }
265
266 fn visit_seq<A: de::SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
267 self.callback.push_index();
268 let result = self.seq_loop(seq);
269 self.callback.pop_index();
270 result
271 }
272
273 fn visit_map<A: de::MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
274 self.callback.push_key();
275 let result = self.map_loop(map);
276 self.callback.pop_key();
277 result
278 }
279}
280
281struct MapKeyVisitor;
282
283impl<'de> de::DeserializeSeed<'de> for MapKeyVisitor {
284 type Value = Cow<'de, str>;
285
286 fn deserialize<D: de::Deserializer<'de>>(
287 self,
288 deserializer: D,
289 ) -> Result<Self::Value, D::Error> {
290 deserializer.deserialize_str(self)
291 }
292}
293
294impl<'de> de::Visitor<'de> for MapKeyVisitor {
295 type Value = Cow<'de, str>;
296
297 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
298 write!(formatter, "a string")
299 }
300
301 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
302 Ok(Cow::Owned(v.to_owned()))
303 }
304
305 fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
306 Ok(Cow::Borrowed(v))
307 }
308
309 fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
310 Ok(Cow::Owned(v))
311 }
312}