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