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 Some((key, value)) = iter.next() else {
64 unreachable!("object is not empty but has no next");
66 };
67 self.indent();
68 stry!(self.new_line());
69 stry!(self.write_simple_string(key));
70 stry!(self.write_min(b": ", b':'));
71 stry!(self.write_json(value));
72
73 for (key, value) in iter {
74 stry!(self.write(b","));
75 stry!(self.new_line());
76 stry!(self.write_simple_string(key));
77 stry!(self.write_min(b": ", b':'));
78 stry!(self.write_json(value));
79 }
80 self.dedent();
81 stry!(self.new_line());
82 self.write(b"}")
83 }
84 }
85
86 #[cfg_attr(not(feature = "no-inline"), inline)]
87 fn write_json(&mut self, json: &Value) -> io::Result<()> {
88 match *json {
89 Value::Static(StaticNode::Null) => self.write(b"null"),
90 Value::Static(StaticNode::I64(number)) => self.write_int(number),
91 #[cfg(feature = "128bit")]
92 Value::Static(StaticNode::I128(number)) => self.write_int(number),
93 Value::Static(StaticNode::U64(number)) => self.write_int(number),
94 #[cfg(feature = "128bit")]
95 Value::Static(StaticNode::U128(number)) => self.write_int(number),
96 #[allow(clippy::useless_conversion)] Value::Static(StaticNode::F64(number)) => self.write_float(number.into()),
98 Value::Static(StaticNode::Bool(true)) => self.write(b"true"),
99 Value::Static(StaticNode::Bool(false)) => self.write(b"false"),
100 Value::String(ref string) => self.write_string(string),
101 Value::Array(ref array) => {
102 if array.is_empty() {
103 self.write(b"[]")
104 } else {
105 let mut iter = <[Value]>::iter(array);
106 let Some(item) = iter.next() else {
109 unreachable!("array is not empty but has no next");
111 };
112
113 stry!(self.write(b"["));
114
115 self.indent();
116 stry!(self.new_line());
117 stry!(self.write_json(item));
118
119 for item in iter {
120 stry!(self.write(b","));
121 stry!(self.new_line());
122 stry!(self.write_json(item));
123 }
124
125 self.dedent();
126 stry!(self.new_line());
127 self.write(b"]")
128 }
129 }
130 Value::Object(ref object) => self.write_object(object),
131 }
132 }
133}
134
135trait FastGenerator: BaseGenerator {
136 type T: Write;
137
138 #[cfg_attr(not(feature = "no-inline"), inline)]
139 fn write_object(&mut self, object: &Object) -> io::Result<()> {
140 if object.is_empty() {
141 self.write(b"{}")
142 } else {
143 let mut iter = object.iter();
144 stry!(self.write(b"{\""));
145
146 let Some((key, value)) = iter.next() else {
148 unreachable!("object is not empty but has no next");
150 };
151 stry!(self.write_simple_str_content(key));
152 stry!(self.write(b"\":"));
153 stry!(self.write_json(value));
154
155 for (key, value) in iter {
156 stry!(self.write(b",\""));
157 stry!(self.write_simple_str_content(key));
158 stry!(self.write(b"\":"));
159 stry!(self.write_json(value));
160 }
161 self.write(b"}")
162 }
163 }
164
165 #[cfg_attr(not(feature = "no-inline"), inline)]
166 fn write_json(&mut self, json: &Value) -> io::Result<()> {
167 match *json {
168 Value::Static(StaticNode::Null) => self.write(b"null"),
169 Value::Static(StaticNode::I64(number)) => self.write_int(number),
170 #[cfg(feature = "128bit")]
171 Value::Static(StaticNode::I128(number)) => self.write_int(number),
172 Value::Static(StaticNode::U64(number)) => self.write_int(number),
173 #[cfg(feature = "128bit")]
174 Value::Static(StaticNode::U128(number)) => self.write_int(number),
175 #[allow(clippy::useless_conversion)] Value::Static(StaticNode::F64(number)) => self.write_float(number.into()),
177 Value::Static(StaticNode::Bool(true)) => self.write(b"true"),
178 Value::Static(StaticNode::Bool(false)) => self.write(b"false"),
179 Value::String(ref string) => self.write_string(string),
180 Value::Array(ref array) => {
181 if array.is_empty() {
182 self.write(b"[]")
183 } else {
184 let mut iter = <[Value]>::iter(array);
185 let Some(item) = iter.next() else {
187 unreachable!("array is not empty but has no next");
189 };
190
191 stry!(self.write(b"["));
192 stry!(self.write_json(item));
193
194 for item in iter {
195 stry!(self.write(b","));
196 stry!(self.write_json(item));
197 }
198 self.write(b"]")
199 }
200 }
201 Value::Object(ref object) => self.write_object(object),
202 }
203 }
204}
205
206impl FastGenerator for DumpGenerator {
207 type T = Vec<u8>;
208}
209
210impl Generator for PrettyGenerator {
211 type T = Vec<u8>;
212}
213
214impl<W> FastGenerator for WriterGenerator<'_, W>
215where
216 W: Write,
217{
218 type T = W;
219}
220
221impl<W> Generator for PrettyWriterGenerator<'_, W>
222where
223 W: Write,
224{
225 type T = W;
226}
227
228#[cfg(test)]
229mod test {
230 use super::Value;
231 use crate::prelude::*;
232
233 #[test]
234 fn null() {
235 assert_eq!(Value::Static(StaticNode::Null).encode(), "null");
236 }
237 #[test]
238 fn bool_true() {
239 assert_eq!(Value::Static(StaticNode::Bool(true)).encode(), "true");
240 }
241 #[test]
242 fn bool_false() {
243 assert_eq!(Value::Static(StaticNode::Bool(false)).encode(), "false");
244 }
245
246 #[test]
247 fn obj() {
248 let mut o = Value::object();
249 o.insert("k", ()).expect("insert");
250 assert_eq!(o.encode(), r#"{"k":null}"#);
251 }
252 fn assert_str(from: &str, to: &str) {
253 assert_eq!(Value::String(from.into()).encode(), to);
254 }
255
256 #[test]
257 fn string() {
258 assert_str("this is a test", r#""this is a test""#);
259 assert_str(r#"this is a test ""#, r#""this is a test \"""#);
260 assert_str(r#"this is a test """#, r#""this is a test \"\"""#);
261 assert_str(
262 "this is a test a long test that should span the 32 byte boundary",
263 r#""this is a test a long test that should span the 32 byte boundary""#,
264 );
265 assert_str(
266 r#"this is a test a "long" test that should span the 32 byte boundary"#,
267 r#""this is a test a \"long\" test that should span the 32 byte boundary""#,
268 );
269
270 assert_str(
271 r#"this is a test a \"long\" test that should span the 32 byte boundary"#,
272 r#""this is a test a \\\"long\\\" test that should span the 32 byte boundary""#,
273 );
274 }
275}