dezoomify_rs/
json_utils.rs1use std::fmt::Display;
2use std::str::FromStr;
3
4use serde::{Deserialize, Deserializer};
5
6struct IterJson<'a> {
8 s: &'a [u8],
9 start_pos: Vec<usize>,
10 current_pos: usize,
11}
12
13impl<'a> IterJson<'a> {
14 fn new(s: &'a [u8]) -> Self {
15 let start_pos = Vec::with_capacity(8);
16 IterJson { s, start_pos, current_pos: 0 }
17 }
18}
19
20impl<'a> Iterator for IterJson<'a> {
21 type Item = &'a [u8];
22
23 fn next(&mut self) -> Option<Self::Item> {
24 while let Some(c) = self.s.get(self.current_pos) {
25 match c {
26 b'{' => { self.start_pos.push(self.current_pos) }
27 b'}' => {
28 if let Some(start) = self.start_pos.pop() {
29 self.current_pos += 1;
30 return Some(&self.s[start..self.current_pos]);
31 }
32 }
33 _ => {}
34 }
35 self.current_pos += 1;
36 }
37 None
38 }
39}
40
41pub fn all_json<'a, T>(bytes: &'a [u8]) -> impl Iterator<Item=T> + 'a
43 where T: Deserialize<'a> + 'a {
44 IterJson::new(bytes)
45 .flat_map(|bytes| std::str::from_utf8(bytes).into_iter())
46 .flat_map(|x| json5::from_str(x).into_iter())
47}
48
49
50pub fn number_or_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
52 where
53 D: Deserializer<'de>,
54 T: FromStr + serde::Deserialize<'de>,
55 <T as FromStr>::Err: Display,
56{
57 #[derive(Deserialize)]
58 #[serde(untagged)]
59 enum StringOrInt<T> {
60 String(String),
61 Number(T),
62 }
63
64 match StringOrInt::<T>::deserialize(deserializer)? {
65 StringOrInt::String(s) => s.parse::<T>().map_err(serde::de::Error::custom),
66 StringOrInt::Number(i) => Ok(i),
67 }
68}
69
70#[test]
71fn test_iterjson() {
72 fn f(s: &str) -> Vec<String> {
73 IterJson::new(s.as_bytes())
74 .map(|s| String::from_utf8_lossy(s).to_string())
75 .collect()
76 }
77 assert_eq!(f(" { a { b { c } d { e } f {{ g }} "), vec!["{ c }", "{ e }", "{ g }", "{{ g }}"]);
78 assert_eq!(f(r#"{"k":{"k":"v"}}"#), vec![r#"{"k":"v"}"#, r#"{"k":{"k":"v"}}"#]);
79 assert_eq!(f(r#"xxx}}xx{{xxx{a}"#), vec!["{a}"]);
80 let only_open = String::from_utf8(vec![b'{'; 1000000]).unwrap();
81 assert_eq!(f(&only_open), Vec::<String>::new());
82}
83
84#[test]
85fn test_alljson() {
86 #[derive(Deserialize, Debug, PartialEq, Eq)]
87 struct S { x: u8 }
88 let actual: Vec<S> = all_json(&br#"{{ "x":1}{-}--{{{"x":2}}"#[..]).collect();
89 assert_eq!(actual, vec![S { x: 1 }, S { x: 2 }]);
90}