encoder/json/
object.rs

1use super::Encode;
2use indexmap::IndexMap;
3use std::collections::HashMap;
4use std::collections::BTreeMap;
5
6/// Encode Object
7/// 
8/// ```
9/// use encoder::json::Encode;
10/// use indexmap::IndexMap;
11/// use std::collections::HashMap;
12/// use std::collections::BTreeMap;
13/// 
14/// {
15///     let mut buf = vec![];
16///     let mut map = HashMap::new();
17///     map.insert("hello", "world\n");
18///     map.insert("aloha", "honua\n");
19///     map.encode(&mut buf);
20///     assert_eq!(unsafe { simd_json::from_str::<HashMap<&str, &str>>(map.stringify().as_mut_str()).unwrap() }, map);
21///     assert_eq!(simd_json::from_slice::<HashMap<&str, &str>>(buf.as_mut_slice()).unwrap(), map);
22/// }
23/// 
24/// {
25///     let mut buf = vec![];
26///     let mut map = HashMap::new();
27///     map.insert(123, "world\n");
28///     map.insert(456, "honua\n");
29///     map.encode(&mut buf);
30///     assert_eq!(unsafe { simd_json::from_str::<HashMap<i32, &str>>(map.stringify().as_mut_str()).unwrap() }, map);
31///     assert_eq!(simd_json::from_slice::<HashMap<i32, &str>>(buf.as_mut_slice()).unwrap(), map);
32/// }
33/// 
34/// {
35///     let mut buf = vec![];
36///     let mut map = BTreeMap::new();
37///     map.insert("hello", "world\n");
38///     map.insert("aloha", "honua\n");
39///     map.encode(&mut buf);
40///     assert_eq!(map.stringify(), r#"{"aloha":"honua\n","hello":"world\n"}"#);
41///     assert_eq!(String::from_utf8_lossy(&buf), r#"{"aloha":"honua\n","hello":"world\n"}"#);
42/// }
43/// 
44/// {
45///     let mut buf = vec![];
46///     let mut map = IndexMap::new();
47///     map.insert("aloha", "honua\n");
48///     map.insert("hello", "world\n");
49///     map.encode(&mut buf);
50///     assert_eq!(map.stringify(), r#"{"aloha":"honua\n","hello":"world\n"}"#);
51///     assert_eq!(String::from_utf8_lossy(&buf), r#"{"aloha":"honua\n","hello":"world\n"}"#);
52/// }
53/// 
54/// {
55///     let mut buf = vec![];
56///     let mut map: IndexMap<&str, &dyn Encode> = IndexMap::new();
57///     map.insert("string", &"world");
58///     map.insert("number", &12345);
59///     map.encode(&mut buf);
60///     assert_eq!(map.stringify(), r#"{"string":"world","number":12345}"#);
61///     assert_eq!(String::from_utf8_lossy(&buf), r#"{"string":"world","number":12345}"#);
62/// }
63/// ```
64macro_rules! impl_object {
65    ($t:ident) => {
66        impl<K: Encode, V: Encode> Encode for $t<K, V> {
67            #[inline]
68            fn encode(&self, buf: &mut Vec<u8>) {
69                impl_inner!(self, buf);
70            }
71        }
72
73        impl<K: Encode> Encode for $t<K, &dyn Encode> {
74            #[inline]
75            fn encode(&self, buf: &mut Vec<u8>) {
76                impl_inner!(self, buf);
77            }
78        }
79    };
80}
81
82macro_rules! impl_inner {
83    ($self:expr, $buf:expr) => {
84        $buf.extend_from_slice(b"{");
85
86        for (k, v) in $self {
87            // key
88            let beg = $buf.len();
89            k.encode($buf);
90
91            match $buf.last() {
92                Some(val) if *val == b'"' => $buf.extend_from_slice(b":"),
93                _ => {
94                    $buf.insert(beg, b'"');
95                    $buf.extend_from_slice(b"\":");
96                }
97            }
98
99            // val
100            v.encode($buf);
101            $buf.extend_from_slice(b",");
102        }
103
104        match $buf.last_mut() {
105            Some(val) if *val == b',' => *val = b'}',
106            _ => $buf.extend_from_slice(b"}"),
107        }
108    };
109}
110
111impl_object!(HashMap);
112impl_object!(BTreeMap);
113impl_object!(IndexMap);