snops_common/format/
impl_json.rs1use 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}