simd_json/value/borrowed/
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<'value> Writable for Value<'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 stry!(self.write(b"["));
117 self.indent();
118
119 stry!(self.new_line());
120 stry!(self.write_json(item));
121
122 for item in iter {
123 stry!(self.write(b","));
124 stry!(self.new_line());
125 stry!(self.write_json(item));
126 }
127 self.dedent();
128 stry!(self.new_line());
129 self.write(b"]")
130 }
131 }
132 Value::Object(ref object) => self.write_object(object),
133 }
134 }
135}
136
137trait FastGenerator: BaseGenerator {
138 type T: Write;
139
140 #[cfg_attr(not(feature = "no-inline"), inline)]
141 fn write_object(&mut self, object: &Object) -> io::Result<()> {
142 if object.is_empty() {
143 self.write(b"{}")
144 } else {
145 let mut iter = object.iter();
146 stry!(self.write(b"{\""));
147
148 let (key, value) = if let Some(v) = iter.next() {
150 v
151 } else {
152 unreachable!();
154 };
155 stry!(self.write_simple_str_content(key));
156 stry!(self.write(b"\":"));
157 stry!(self.write_json(value));
158
159 for (key, value) in iter {
160 stry!(self.write(b",\""));
161 stry!(self.write_simple_str_content(key));
162 stry!(self.write(b"\":"));
163 stry!(self.write_json(value));
164 }
165 self.write(b"}")
166 }
167 }
168
169 #[cfg_attr(not(feature = "no-inline"), inline)]
170 fn write_json(&mut self, json: &Value) -> io::Result<()> {
171 match *json {
172 Value::Static(StaticNode::Null) => self.write(b"null"),
173 Value::Static(StaticNode::I64(number)) => self.write_int(number),
174 #[cfg(feature = "128bit")]
175 Value::Static(StaticNode::I128(number)) => self.write_int(number),
176 Value::Static(StaticNode::U64(number)) => self.write_int(number),
177 #[cfg(feature = "128bit")]
178 Value::Static(StaticNode::U128(number)) => self.write_int(number),
179 #[allow(clippy::useless_conversion)] Value::Static(StaticNode::F64(number)) => self.write_float(number.into()),
181 Value::Static(StaticNode::Bool(true)) => self.write(b"true"),
182 Value::Static(StaticNode::Bool(false)) => self.write(b"false"),
183 Value::String(ref string) => self.write_string(string),
184 Value::Array(ref array) => {
185 if array.is_empty() {
186 self.write(b"[]")
187 } else {
188 let mut iter = <[Value]>::iter(array);
189 let item = if let Some(v) = iter.next() {
191 v
192 } else {
193 unreachable!();
195 };
196
197 stry!(self.write(b"["));
198 stry!(self.write_json(item));
199
200 for item in iter {
201 stry!(self.write(b","));
202 stry!(self.write_json(item));
203 }
204 self.write(b"]")
205 }
206 }
207 Value::Object(ref object) => self.write_object(object),
208 }
209 }
210}
211
212impl FastGenerator for DumpGenerator {
213 type T = Vec<u8>;
214}
215
216impl Generator for PrettyGenerator {
217 type T = Vec<u8>;
218}
219
220impl<'writer, W> FastGenerator for WriterGenerator<'writer, W>
221where
222 W: Write,
223{
224 type T = W;
225}
226
227impl<'writer, W> Generator for PrettyWriterGenerator<'writer, W>
228where
229 W: Write,
230{
231 type T = W;
232}
233
234#[cfg(test)]
235mod test {
236 use super::Value;
237 use crate::prelude::*;
238
239 #[test]
240 fn null() {
241 assert_eq!(Value::Static(StaticNode::Null).encode(), "null");
242 }
243 #[test]
244 fn bool_true() {
245 assert_eq!(Value::Static(StaticNode::Bool(true)).encode(), "true");
246 }
247 #[test]
248 fn bool_false() {
249 assert_eq!(Value::Static(StaticNode::Bool(false)).encode(), "false");
250 }
251
252 #[test]
253 fn obj() {
254 let mut o = Value::object();
255 o.insert("k", ()).expect("insert");
256 assert_eq!(o.encode(), r#"{"k":null}"#);
257 }
258
259 fn assert_str(from: &str, to: &str) {
260 assert_eq!(Value::String(from.into()).encode(), to);
261 }
262 #[test]
263 fn string() {
264 assert_str("this is a test", r#""this is a test""#);
265 assert_str(r#"this is a test ""#, r#""this is a test \"""#);
266 assert_str(r#"this is a test """#, r#""this is a test \"\"""#);
267 assert_str(
268 "this is a test a long test that should span the 32 byte boundary",
269 r#""this is a test a long test that should span the 32 byte boundary""#,
270 );
271 assert_str(
272 r#"this is a test a "long" test that should span the 32 byte boundary"#,
273 r#""this is a test a \"long\" test that should span the 32 byte boundary""#,
274 );
275
276 assert_str(
277 r#"this is a test a \"long\" test that should span the 32 byte boundary"#,
278 r#""this is a test a \\\"long\\\" test that should span the 32 byte boundary""#,
279 );
280 }
281}