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);