snops_common/format/
impl_json.rs

1use super::{DataFormat, PackedUint};
2
3impl DataFormat for serde_json::Value {
4    type Header = ();
5    const LATEST_HEADER: Self::Header = ();
6
7    fn write_data<W: std::io::prelude::Write>(
8        &self,
9        writer: &mut W,
10    ) -> Result<usize, crate::format::DataWriteError> {
11        let bytes = serde_json::to_vec(self)
12            .map_err(|e| crate::format::DataWriteError::Custom(format!("json to bytes: {e:?}")))?;
13
14        Ok(PackedUint::from(bytes.len()).write_data(writer)? + writer.write(&bytes)?)
15    }
16
17    fn read_data<R: std::io::prelude::Read>(
18        reader: &mut R,
19        _header: &Self::Header,
20    ) -> Result<Self, crate::format::DataReadError> {
21        let len = usize::from(PackedUint::read_data(reader, &())?);
22        let mut buf = vec![0; len];
23        reader.read_exact(&mut buf)?;
24        serde_json::from_slice(&buf)
25            .map_err(|e| crate::format::DataReadError::Custom(format!("json from bytes: {e:?}")))
26    }
27}
28
29#[cfg(test)]
30#[rustfmt::skip]
31mod test {
32
33    use serde_json::json;
34
35    use crate::format::DataFormat;
36    use crate::format::PackedUint;
37
38    macro_rules! case {
39        ($name:ident, $ty:ty, $a:expr) => {
40            #[test]
41            fn $name() {
42                let mut data = Vec::new();
43                let vec_raw = serde_json::to_vec(&$a).unwrap();
44                let mut vec = PackedUint::from(vec_raw.len()).to_byte_vec().unwrap();
45                vec.extend(vec_raw);
46
47                $a.write_data(&mut data).unwrap();
48                assert_eq!(data, vec);
49
50                let mut reader = &data[..];
51                let read_value = <$ty>::read_data(&mut reader, &()).unwrap();
52                assert_eq!(read_value, $a);
53            }
54
55        };
56    }
57
58    case!(test_json_null, serde_json::Value, serde_json::Value::Null);
59    case!(test_json_bool, serde_json::Value, serde_json::Value::Bool(true));
60    case!(test_json_number, serde_json::Value, serde_json::Value::Number(serde_json::Number::from_f64(1.23).unwrap()));
61    case!(test_json_string, serde_json::Value, serde_json::Value::String("hello".to_string()));
62    case!(test_json_array, serde_json::Value, serde_json::Value::Array(vec![
63        serde_json::Value::Null,
64        serde_json::Value::Bool(true),
65        serde_json::Value::Number(serde_json::Number::from_f64(1.23).unwrap()),
66        serde_json::Value::String("hello".to_string()),
67    ]));
68    case!(test_json_object, serde_json::Value, serde_json::Value::Object({
69        let mut map = serde_json::Map::new();
70        map.insert("null".to_string(), serde_json::Value::Null);
71        map.insert("bool".to_string(), serde_json::Value::Bool(true));
72        map.insert("number".to_string(), serde_json::Value::Number(serde_json::Number::from_f64(1.23).unwrap()));
73        map.insert("string".to_string(), serde_json::Value::String("hello".to_string()));
74        map
75    }));
76    case!(test_json_complex, serde_json::Value, json!({
77        "null": null,
78        "bool": true,
79        "number": 1.23,
80        "string": "hello",
81        "array": [null, true, 1.23, "hello"],
82        "object": {
83            "null": null,
84            "bool": true,
85            "number": 1.23,
86            "string": "hello"
87        }
88    }));
89}