simd_json/value/owned/
serialize.rs1use super::{Object, Value};
8use crate::prelude::*;
9use std::io;
10use std::io::Write;
11use value_trait::generator::{
12 DumpGenerator, PrettyGenerator, PrettyWriterGenerator, WriterGenerator,
13};
14
15impl Writable for Value {
18 #[cfg_attr(not(feature = "no-inline"), inline)]
19 fn encode(&self) -> String {
20 let mut g = DumpGenerator::new();
21 let _r = g.write_json(self);
22 g.consume()
23 }
24
25 #[cfg_attr(not(feature = "no-inline"), inline)]
26 fn encode_pp(&self) -> String {
27 let mut g = PrettyGenerator::new(2);
28 let _r = g.write_json(self);
29 g.consume()
30 }
31
32 #[cfg_attr(not(feature = "no-inline"), inline)]
33 fn write<'writer, W>(&self, w: &mut W) -> io::Result<()>
34 where
35 W: 'writer + Write,
36 {
37 let mut g = WriterGenerator::new(w);
38 g.write_json(self)
39 }
40
41 #[cfg_attr(not(feature = "no-inline"), inline)]
42 fn write_pp<'writer, W>(&self, w: &mut W) -> io::Result<()>
43 where
44 W: 'writer + Write,
45 {
46 let mut g = PrettyWriterGenerator::new(w, 2);
47 g.write_json(self)
48 }
49}
50
51trait Generator: BaseGenerator {
52 type T: Write;
53
54 #[cfg_attr(not(feature = "no-inline"), inline)]
55 fn write_object(&mut self, object: &Object) -> io::Result<()> {
56 if object.is_empty() {
57 self.write(b"{}")
58 } else {
59 let mut iter = object.iter();
60 stry!(self.write(b"{"));
61
62 let (key, value) = if let Some(v) = iter.next() {
64 v
65 } else {
66 unreachable!();
68 };
69 self.indent();
70 stry!(self.new_line());
71 stry!(self.write_simple_string(key));
72 stry!(self.write_min(b": ", b':'));
73 stry!(self.write_json(value));
74
75 for (key, value) in iter {
76 stry!(self.write(b","));
77 stry!(self.new_line());
78 stry!(self.write_simple_string(key));
79 stry!(self.write_min(b": ", b':'));
80 stry!(self.write_json(value));
81 }
82 self.dedent();
83 stry!(self.new_line());
84 self.write(b"}")
85 }
86 }
87
88 #[cfg_attr(not(feature = "no-inline"), inline)]
89 fn write_json(&mut self, json: &Value) -> io::Result<()> {
90 match *json {
91 Value::Static(StaticNode::Null) => self.write(b"null"),
92 Value::Static(StaticNode::I64(number)) => self.write_int(number),
93 #[cfg(feature = "128bit")]
94 Value::Static(StaticNode::I128(number)) => self.write_int(number),
95 Value::Static(StaticNode::U64(number)) => self.write_int(number),
96 #[cfg(feature = "128bit")]
97 Value::Static(StaticNode::U128(number)) => self.write_int(number),
98 #[allow(clippy::useless_conversion)] Value::Static(StaticNode::F64(number)) => self.write_float(number.into()),
100 Value::Static(StaticNode::Bool(true)) => self.write(b"true"),
101 Value::Static(StaticNode::Bool(false)) => self.write(b"false"),
102 Value::String(ref string) => self.write_string(string),
103 Value::Array(ref array) => {
104 if array.is_empty() {
105 self.write(b"[]")
106 } else {
107 let mut iter = <[Value]>::iter(array);
108 let item = if let Some(v) = iter.next() {
111 v
112 } else {
113 unreachable!();
115 };
116
117 stry!(self.write(b"["));
118
119 self.indent();
120 stry!(self.new_line());
121 stry!(self.write_json(item));
122
123 for item in iter {
124 stry!(self.write(b","));
125 stry!(self.new_line());
126 stry!(self.write_json(item));
127 }
128
129 self.dedent();
130 stry!(self.new_line());
131 self.write(b"]")
132 }
133 }
134 Value::Object(ref object) => self.write_object(object),
135 }
136 }
137}
138
139trait FastGenerator: BaseGenerator {
140 type T: Write;
141
142 #[cfg_attr(not(feature = "no-inline"), inline)]
143 fn write_object(&mut self, object: &Object) -> io::Result<()> {
144 if object.is_empty() {
145 self.write(b"{}")
146 } else {
147 let mut iter = object.iter();
148 stry!(self.write(b"{\""));
149
150 let (key, value) = if let Some(v) = iter.next() {
152 v
153 } else {
154 unreachable!();
156 };
157 stry!(self.write_simple_str_content(key));
158 stry!(self.write(b"\":"));
159 stry!(self.write_json(value));
160
161 for (key, value) in iter {
162 stry!(self.write(b",\""));
163 stry!(self.write_simple_str_content(key));
164 stry!(self.write(b"\":"));
165 stry!(self.write_json(value));
166 }
167 self.write(b"}")
168 }
169 }
170
171 #[cfg_attr(not(feature = "no-inline"), inline)]
172 fn write_json(&mut self, json: &Value) -> io::Result<()> {
173 match *json {
174 Value::Static(StaticNode::Null) => self.write(b"null"),
175 Value::Static(StaticNode::I64(number)) => self.write_int(number),
176 #[cfg(feature = "128bit")]
177 Value::Static(StaticNode::I128(number)) => self.write_int(number),
178 Value::Static(StaticNode::U64(number)) => self.write_int(number),
179 #[cfg(feature = "128bit")]
180 Value::Static(StaticNode::U128(number)) => self.write_int(number),
181 #[allow(clippy::useless_conversion)] Value::Static(StaticNode::F64(number)) => self.write_float(number.into()),
183 Value::Static(StaticNode::Bool(true)) => self.write(b"true"),
184 Value::Static(StaticNode::Bool(false)) => self.write(b"false"),
185 Value::String(ref string) => self.write_string(string),
186 Value::Array(ref array) => {
187 if array.is_empty() {
188 self.write(b"[]")
189 } else {
190 let mut iter = <[Value]>::iter(array);
191 let item = if let Some(v) = iter.next() {
193 v
194 } else {
195 unreachable!();
197 };
198
199 stry!(self.write(b"["));
200 stry!(self.write_json(item));
201
202 for item in iter {
203 stry!(self.write(b","));
204 stry!(self.write_json(item));
205 }
206 self.write(b"]")
207 }
208 }
209 Value::Object(ref object) => self.write_object(object),
210 }
211 }
212}
213
214impl FastGenerator for DumpGenerator {
215 type T = Vec<u8>;
216}
217
218impl Generator for PrettyGenerator {
219 type T = Vec<u8>;
220}
221
222impl<'writer, W> FastGenerator for WriterGenerator<'writer, W>
223where
224 W: Write,
225{
226 type T = W;
227}
228
229impl<'writer, W> Generator for PrettyWriterGenerator<'writer, W>
230where
231 W: Write,
232{
233 type T = W;
234}
235
236#[cfg(test)]
237mod test {
238 use super::Value;
239 use crate::prelude::*;
240
241 #[test]
242 fn null() {
243 assert_eq!(Value::Static(StaticNode::Null).encode(), "null");
244 }
245 #[test]
246 fn bool_true() {
247 assert_eq!(Value::Static(StaticNode::Bool(true)).encode(), "true");
248 }
249 #[test]
250 fn bool_false() {
251 assert_eq!(Value::Static(StaticNode::Bool(false)).encode(), "false");
252 }
253
254 #[test]
255 fn obj() {
256 let mut o = Value::object();
257 o.insert("k", ()).expect("insert");
258 assert_eq!(o.encode(), r#"{"k":null}"#);
259 }
260 fn assert_str(from: &str, to: &str) {
261 assert_eq!(Value::String(from.into()).encode(), to);
262 }
263
264 #[test]
265 fn string() {
266 assert_str("this is a test", r#""this is a test""#);
267 assert_str(r#"this is a test ""#, r#""this is a test \"""#);
268 assert_str(r#"this is a test """#, r#""this is a test \"\"""#);
269 assert_str(
270 "this is a test a long test that should span the 32 byte boundary",
271 r#""this is a test a long test that should span the 32 byte boundary""#,
272 );
273 assert_str(
274 r#"this is a test a "long" test that should span the 32 byte boundary"#,
275 r#""this is a test a \"long\" test that should span the 32 byte boundary""#,
276 );
277
278 assert_str(
279 r#"this is a test a \"long\" test that should span the 32 byte boundary"#,
280 r#""this is a test a \\\"long\\\" test that should span the 32 byte boundary""#,
281 );
282 }
283}