Skip to main content

dada_util/
fixed_depth_json.rs

1use lazy_static::lazy_static;
2use serde::ser::{
3    self, Error, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
4    SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
5};
6use std::collections::HashSet;
7
8// Global deny list for fields to exclude from debug JSON output
9lazy_static! {
10    pub static ref DEBUG_FIELD_DENY_LIST: HashSet<&'static str> = {
11        let mut set = HashSet::new();
12        set.insert("super_scope");
13        set.insert("super_scope_item");
14        set.insert("contents");
15        set
16    };
17}
18
19/// Create a JSON value for `value` but only up to a limited depth.
20/// Values past that depth are represented as a "..." string.
21pub fn to_json_value_max_depth(
22    value: &dyn erased_serde::Serialize,
23    max_depth: usize,
24) -> serde_json::Value {
25    let serializer = MaxDepthSerializer::new(max_depth);
26    value
27        .serialize(serializer)
28        .unwrap_or(serde_json::Value::Null)
29}
30struct MaxDepthSerializer {
31    current_depth: usize,
32    max_depth: usize,
33}
34
35impl MaxDepthSerializer {
36    fn new(max_depth: usize) -> Self {
37        Self {
38            current_depth: 0,
39            max_depth,
40        }
41    }
42
43    fn should_truncate(&self) -> bool {
44        self.current_depth >= self.max_depth
45    }
46}
47
48impl ser::Serializer for MaxDepthSerializer {
49    type Ok = serde_json::Value;
50    type Error = serde_json::Error;
51    type SerializeSeq = MaxDepthSeq;
52    type SerializeTuple = MaxDepthSeq;
53    type SerializeTupleStruct = MaxDepthSeq;
54    type SerializeTupleVariant = MaxDepthSeq;
55    type SerializeMap = MaxDepthMap;
56    type SerializeStruct = MaxDepthMap;
57    type SerializeStructVariant = MaxDepthMap;
58
59    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
60        Ok(serde_json::Value::Bool(v))
61    }
62
63    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
64        Ok(serde_json::Value::Number(v.into()))
65    }
66
67    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
68        Ok(serde_json::Value::Number(v.into()))
69    }
70
71    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
72        Ok(serde_json::Value::Number(v.into()))
73    }
74
75    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
76        Ok(serde_json::Value::Number(v.into()))
77    }
78
79    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
80        Ok(serde_json::Value::Number(v.into()))
81    }
82
83    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
84        Ok(serde_json::Value::Number(v.into()))
85    }
86
87    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
88        Ok(serde_json::Value::Number(v.into()))
89    }
90
91    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
92        Ok(serde_json::Value::Number(v.into()))
93    }
94
95    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
96        Ok(serde_json::Value::Number(
97            serde_json::Number::from_f64(v as f64)
98                .ok_or(serde_json::Error::custom("float conversion failed"))?,
99        ))
100    }
101
102    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
103        Ok(serde_json::Value::Number(
104            serde_json::Number::from_f64(v)
105                .ok_or(serde_json::Error::custom("float conversion failed"))?,
106        ))
107    }
108
109    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
110        Ok(serde_json::Value::String(v.to_string()))
111    }
112
113    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
114        Ok(serde_json::Value::String(v.to_owned()))
115    }
116
117    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
118        Ok(serde_json::Value::Array(
119            v.iter()
120                .map(|&b| serde_json::Value::Number(b.into()))
121                .collect(),
122        ))
123    }
124
125    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
126        Ok(serde_json::Value::Null)
127    }
128
129    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
130    where
131        T: ?Sized + Serialize,
132    {
133        value.serialize(self)
134    }
135
136    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
137        Ok(serde_json::Value::Null)
138    }
139
140    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
141        Ok(serde_json::Value::Null)
142    }
143
144    fn serialize_unit_variant(
145        self,
146        _name: &'static str,
147        _variant_index: u32,
148        variant: &'static str,
149    ) -> Result<Self::Ok, Self::Error> {
150        Ok(serde_json::Value::String(variant.to_owned()))
151    }
152
153    fn serialize_newtype_struct<T>(
154        self,
155        _name: &'static str,
156        value: &T,
157    ) -> Result<Self::Ok, Self::Error>
158    where
159        T: ?Sized + Serialize,
160    {
161        value.serialize(self)
162    }
163
164    fn serialize_newtype_variant<T>(
165        self,
166        _name: &'static str,
167        _variant_index: u32,
168        variant: &'static str,
169        value: &T,
170    ) -> Result<Self::Ok, Self::Error>
171    where
172        T: ?Sized + Serialize,
173    {
174        let mut map = serde_json::Map::new();
175        map.insert(variant.to_owned(), value.serialize(self)?);
176        Ok(serde_json::Value::Object(map))
177    }
178
179    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
180        if self.should_truncate() {
181            Ok(MaxDepthSeq::Truncated)
182        } else {
183            Ok(MaxDepthSeq::Active {
184                serializer: MaxDepthSerializer {
185                    current_depth: self.current_depth + 1,
186                    max_depth: self.max_depth,
187                },
188                vec: Vec::with_capacity(len.unwrap_or(0)),
189            })
190        }
191    }
192
193    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
194        self.serialize_seq(Some(len))
195    }
196
197    fn serialize_tuple_struct(
198        self,
199        _name: &'static str,
200        len: usize,
201    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
202        self.serialize_seq(Some(len))
203    }
204
205    fn serialize_tuple_variant(
206        self,
207        _name: &'static str,
208        _variant_index: u32,
209        variant: &'static str,
210        len: usize,
211    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
212        if self.should_truncate() {
213            Ok(MaxDepthSeq::Truncated)
214        } else {
215            Ok(MaxDepthSeq::VariantActive {
216                serializer: MaxDepthSerializer {
217                    current_depth: self.current_depth + 1,
218                    max_depth: self.max_depth,
219                },
220                variant: variant.to_owned(),
221                vec: Vec::with_capacity(len),
222            })
223        }
224    }
225
226    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
227        if self.should_truncate() {
228            Ok(MaxDepthMap::Truncated)
229        } else {
230            Ok(MaxDepthMap::Active {
231                serializer: MaxDepthSerializer {
232                    current_depth: self.current_depth + 1,
233                    max_depth: self.max_depth,
234                },
235                map: serde_json::Map::with_capacity(len.unwrap_or(0)),
236                next_key: None,
237            })
238        }
239    }
240
241    fn serialize_struct(
242        self,
243        _name: &'static str,
244        len: usize,
245    ) -> Result<Self::SerializeStruct, Self::Error> {
246        self.serialize_map(Some(len))
247    }
248
249    fn serialize_struct_variant(
250        self,
251        _name: &'static str,
252        _variant_index: u32,
253        variant: &'static str,
254        len: usize,
255    ) -> Result<Self::SerializeStructVariant, Self::Error> {
256        if self.should_truncate() {
257            Ok(MaxDepthMap::Truncated)
258        } else {
259            Ok(MaxDepthMap::VariantActive {
260                serializer: MaxDepthSerializer {
261                    current_depth: self.current_depth + 1,
262                    max_depth: self.max_depth,
263                },
264                variant: variant.to_owned(),
265                map: serde_json::Map::with_capacity(len),
266                next_key: None,
267            })
268        }
269    }
270}
271
272enum MaxDepthSeq {
273    Active {
274        serializer: MaxDepthSerializer,
275        vec: Vec<serde_json::Value>,
276    },
277    VariantActive {
278        serializer: MaxDepthSerializer,
279        variant: String,
280        vec: Vec<serde_json::Value>,
281    },
282    Truncated,
283}
284
285impl SerializeSeq for MaxDepthSeq {
286    type Ok = serde_json::Value;
287    type Error = serde_json::Error;
288
289    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
290    where
291        T: ?Sized + Serialize,
292    {
293        match self {
294            MaxDepthSeq::Active { serializer, vec } => {
295                vec.push(value.serialize(serializer.clone())?)
296            }
297            MaxDepthSeq::VariantActive {
298                serializer, vec, ..
299            } => vec.push(value.serialize(serializer.clone())?),
300            MaxDepthSeq::Truncated => (),
301        }
302        Ok(())
303    }
304
305    fn end(self) -> Result<Self::Ok, Self::Error> {
306        match self {
307            MaxDepthSeq::Active { vec, .. } => Ok(serde_json::Value::Array(vec)),
308            MaxDepthSeq::VariantActive { variant, vec, .. } => {
309                let mut map = serde_json::Map::new();
310                map.insert(variant, serde_json::Value::Array(vec));
311                Ok(serde_json::Value::Object(map))
312            }
313            MaxDepthSeq::Truncated => Ok(serde_json::Value::String("...".to_owned())),
314        }
315    }
316}
317
318impl SerializeTuple for MaxDepthSeq {
319    type Ok = serde_json::Value;
320    type Error = serde_json::Error;
321
322    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
323    where
324        T: ?Sized + Serialize,
325    {
326        match self {
327            MaxDepthSeq::Active { serializer, vec } => {
328                vec.push(value.serialize(serializer.clone())?)
329            }
330            MaxDepthSeq::VariantActive {
331                serializer, vec, ..
332            } => vec.push(value.serialize(serializer.clone())?),
333            MaxDepthSeq::Truncated => (),
334        }
335        Ok(())
336    }
337
338    fn end(self) -> Result<Self::Ok, Self::Error> {
339        match self {
340            MaxDepthSeq::Active { vec, .. } => Ok(serde_json::Value::Array(vec)),
341            MaxDepthSeq::VariantActive { variant, vec, .. } => {
342                let mut map = serde_json::Map::new();
343                map.insert(variant, serde_json::Value::Array(vec));
344                Ok(serde_json::Value::Object(map))
345            }
346            MaxDepthSeq::Truncated => Ok(serde_json::Value::String("...".to_owned())),
347        }
348    }
349}
350
351impl SerializeTupleStruct for MaxDepthSeq {
352    type Ok = serde_json::Value;
353    type Error = serde_json::Error;
354
355    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
356    where
357        T: ?Sized + Serialize,
358    {
359        match self {
360            MaxDepthSeq::Active { serializer, vec } => {
361                vec.push(value.serialize(serializer.clone())?)
362            }
363            MaxDepthSeq::VariantActive {
364                serializer, vec, ..
365            } => vec.push(value.serialize(serializer.clone())?),
366            MaxDepthSeq::Truncated => (),
367        }
368        Ok(())
369    }
370
371    fn end(self) -> Result<Self::Ok, Self::Error> {
372        match self {
373            MaxDepthSeq::Active { vec, .. } => Ok(serde_json::Value::Array(vec)),
374            MaxDepthSeq::VariantActive { variant, vec, .. } => {
375                let mut map = serde_json::Map::new();
376                map.insert(variant, serde_json::Value::Array(vec));
377                Ok(serde_json::Value::Object(map))
378            }
379            MaxDepthSeq::Truncated => Ok(serde_json::Value::String("...".to_owned())),
380        }
381    }
382}
383
384impl SerializeTupleVariant for MaxDepthSeq {
385    type Ok = serde_json::Value;
386    type Error = serde_json::Error;
387
388    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
389    where
390        T: ?Sized + Serialize,
391    {
392        match self {
393            MaxDepthSeq::Active { serializer, vec } => {
394                vec.push(value.serialize(serializer.clone())?)
395            }
396            MaxDepthSeq::VariantActive {
397                serializer, vec, ..
398            } => vec.push(value.serialize(serializer.clone())?),
399            MaxDepthSeq::Truncated => (),
400        }
401        Ok(())
402    }
403
404    fn end(self) -> Result<Self::Ok, Self::Error> {
405        match self {
406            MaxDepthSeq::Active { vec, .. } => Ok(serde_json::Value::Array(vec)),
407            MaxDepthSeq::VariantActive { variant, vec, .. } => {
408                let mut map = serde_json::Map::new();
409                map.insert(variant, serde_json::Value::Array(vec));
410                Ok(serde_json::Value::Object(map))
411            }
412            MaxDepthSeq::Truncated => Ok(serde_json::Value::String("...".to_owned())),
413        }
414    }
415}
416
417enum MaxDepthMap {
418    Active {
419        serializer: MaxDepthSerializer,
420        map: serde_json::Map<String, serde_json::Value>,
421        next_key: Option<String>,
422    },
423    VariantActive {
424        serializer: MaxDepthSerializer,
425        variant: String,
426        map: serde_json::Map<String, serde_json::Value>,
427        next_key: Option<String>,
428    },
429    Truncated,
430}
431
432impl SerializeMap for MaxDepthMap {
433    type Ok = serde_json::Value;
434    type Error = serde_json::Error;
435
436    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
437    where
438        T: ?Sized + Serialize,
439    {
440        match self {
441            MaxDepthMap::Active { next_key, .. } | MaxDepthMap::VariantActive { next_key, .. } => {
442                *next_key = Some(
443                    key.serialize(MaxDepthSerializer::new(usize::MAX))
444                        .and_then(|v| match v {
445                            serde_json::Value::String(s) => Ok(s),
446                            _ => Err(ser::Error::custom("map key must be a string")),
447                        })?,
448                );
449            }
450            MaxDepthMap::Truncated => (),
451        }
452        Ok(())
453    }
454
455    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
456    where
457        T: ?Sized + Serialize,
458    {
459        match self {
460            MaxDepthMap::Active {
461                serializer,
462                map,
463                next_key,
464            }
465            | MaxDepthMap::VariantActive {
466                serializer,
467                map,
468                next_key,
469                ..
470            } => {
471                let key = next_key.take().ok_or_else(|| {
472                    ser::Error::custom("serialize_value called before serialize_key")
473                })?;
474                map.insert(key, value.serialize(serializer.clone())?);
475            }
476            MaxDepthMap::Truncated => (),
477        }
478        Ok(())
479    }
480
481    fn end(self) -> Result<Self::Ok, Self::Error> {
482        match self {
483            MaxDepthMap::Active { map, .. } => Ok(serde_json::Value::Object(map)),
484            MaxDepthMap::VariantActive { variant, map, .. } => {
485                let mut outer_map = serde_json::Map::new();
486                outer_map.insert(variant, serde_json::Value::Object(map));
487                Ok(serde_json::Value::Object(outer_map))
488            }
489            MaxDepthMap::Truncated => Ok(serde_json::Value::String("...".to_owned())),
490        }
491    }
492}
493
494impl SerializeStruct for MaxDepthMap {
495    type Ok = serde_json::Value;
496    type Error = serde_json::Error;
497
498    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
499    where
500        T: ?Sized + Serialize,
501    {
502        // Skip fields in the deny list
503        if DEBUG_FIELD_DENY_LIST.contains(key) {
504            return Ok(());
505        }
506
507        SerializeMap::serialize_key(self, key)?;
508        SerializeMap::serialize_value(self, value)
509    }
510
511    fn end(self) -> Result<Self::Ok, Self::Error> {
512        SerializeMap::end(self)
513    }
514}
515
516impl SerializeStructVariant for MaxDepthMap {
517    type Ok = serde_json::Value;
518    type Error = serde_json::Error;
519
520    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
521    where
522        T: ?Sized + Serialize,
523    {
524        // Skip fields in the deny list
525        if DEBUG_FIELD_DENY_LIST.contains(key) {
526            return Ok(());
527        }
528
529        match self {
530            MaxDepthMap::Active {
531                serializer, map, ..
532            }
533            | MaxDepthMap::VariantActive {
534                serializer, map, ..
535            } => {
536                map.insert(key.to_owned(), value.serialize(serializer.clone())?);
537            }
538            MaxDepthMap::Truncated => (),
539        }
540        Ok(())
541    }
542
543    fn end(self) -> Result<Self::Ok, Self::Error> {
544        match self {
545            MaxDepthMap::Active { map, .. } => Ok(serde_json::Value::Object(map)),
546            MaxDepthMap::VariantActive { variant, map, .. } => {
547                let mut outer_map = serde_json::Map::new();
548                outer_map.insert(variant, serde_json::Value::Object(map));
549                Ok(serde_json::Value::Object(outer_map))
550            }
551            MaxDepthMap::Truncated => Ok(serde_json::Value::String("...".to_owned())),
552        }
553    }
554}
555
556impl Clone for MaxDepthSerializer {
557    fn clone(&self) -> Self {
558        Self {
559            current_depth: self.current_depth,
560            max_depth: self.max_depth,
561        }
562    }
563}