Skip to main content

json_grep/
lib.rs

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}