1use crate::blocking::io::BlockingWrite;
2use crate::blocking::json_writer::JsonWriter;
3use crate::blocking::object::JsonObject;
4use crate::shared::*;
5
6pub struct JsonArray<'a, 'b, W: BlockingWrite, F: JsonFormatter, FF: FloatFormat> {
17 writer: &'a mut JsonWriter<'b, W, F, FF>,
18 is_initial: bool,
19 is_ended: bool,
20}
21
22impl<'a, 'b, W: BlockingWrite, F: JsonFormatter, FF: FloatFormat> JsonArray<'a, 'b, W, F, FF> {
23 pub fn new(writer: &'a mut JsonWriter<'b, W, F, FF>) -> Result<Self, W::Error> {
26 writer.write_bytes(b"[")?;
27 writer.write_format_after_start_nested()?;
28
29 Ok(JsonArray {
30 writer,
31 is_initial: true,
32 is_ended: false,
33 })
34 }
35
36 fn handle_initial(&mut self) -> Result<(), W::Error> {
37 if self.is_initial {
38 self.is_initial = false;
39 }
40 else {
41 self.writer.write_bytes(b",")?;
42 self.writer.write_format_after_element()?;
43 }
44 self.writer.write_format_indent()?;
45 Ok(())
46 }
47
48 pub fn write_string_value(&mut self, value: &str) -> Result<(), W::Error> {
50 self.handle_initial()?;
51 self.writer.write_escaped_string(value)
52 }
53
54 pub fn write_bool_value(&mut self, value: bool) -> Result<(), W::Error> {
56 self.handle_initial()?;
57 self.writer.write_bool(value)
58 }
59
60 pub fn write_null_value(&mut self) -> Result<(), W::Error> {
62 self.handle_initial()?;
63 self.writer.write_bytes(b"null")
64 }
65
66 pub fn write_f64_value(&mut self, value: f64) -> Result<(), W::Error> {
71 self.handle_initial()?;
72 self.writer.write_f64(value)
73 }
74
75 pub fn write_f32_value(&mut self, value: f32) -> Result<(), W::Error> {
80 self.handle_initial()?;
81 self.writer.write_f32(value)
82 }
83
84 pub fn start_object<'c, 'x>(&'x mut self) -> Result<JsonObject<'c, 'b, W, F, FF>, W::Error>
89 where 'a: 'c, 'x: 'c
90 {
91 self.handle_initial()?;
92 JsonObject::new(self.writer)
93 }
94
95 pub fn start_array<'c, 'x>(&'x mut self) -> Result<JsonArray<'c, 'b, W, F, FF>, W::Error>
100 where 'a: 'c, 'x: 'c
101 {
102 self.handle_initial()?;
103 JsonArray::new(self.writer)
104 }
105
106 pub fn end(self) -> Result<(), W::Error> {
108 let mut mut_self = self;
109 mut_self._end()
110 }
111
112 fn _end(&mut self) -> Result<(), W::Error> {
113 self.writer.write_format_before_end_nested(self.is_initial)?;
114 self.writer.write_bytes(b"]")?;
115 self.is_ended = true;
116 Ok(())
117 }
118}
119
120macro_rules! write_arr_int {
121 ($t:ty ; $f:ident) => {
122impl<'a, 'b, W: BlockingWrite, F: JsonFormatter, FF: FloatFormat> JsonArray<'a, 'b, W, F, FF> {
123 pub fn $f(&mut self, value: $t) -> Result<(), W::Error> {
126 self.handle_initial()?;
127 self.writer.write_raw_num(value)
128 }
129}
130 };
131}
132write_arr_int!(i8; write_i8_value);
133write_arr_int!(u8; write_u8_value);
134write_arr_int!(i16; write_i16_value);
135write_arr_int!(u16; write_u16_value);
136write_arr_int!(i32; write_i32_value);
137write_arr_int!(u32; write_u32_value);
138write_arr_int!(i64; write_i64_value);
139write_arr_int!(u64; write_u64_value);
140write_arr_int!(i128; write_i128_value);
141write_arr_int!(u128; write_u128_value);
142write_arr_int!(isize; write_isize_value);
143write_arr_int!(usize; write_usize_value);
144
145
146
147impl <'a, 'b, W: BlockingWrite, F: JsonFormatter, FF: FloatFormat> Drop for JsonArray<'a, 'b, W, F, FF> {
148 fn drop(&mut self) {
149 if !self.is_ended {
150 if let Err(e) = self._end() {
151 self.writer.set_unreported_error(e);
152 }
153 }
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160 use rstest::*;
161 use std::io;
162
163 type AS<'a, 'b> = JsonArray<'a, 'b, Vec<u8>, CompactFormatter, DefaultFloatFormat>;
164
165 #[rstest]
166 #[case::empty(Box::new(|_ser: &mut AS| Ok(())), "[]")]
167 #[case::single(Box::new(|ser: &mut AS| ser.write_null_value()), "[null]")]
168 #[case::two(Box::new(|ser: &mut AS| { ser.write_u32_value(1)?; ser.write_u32_value(2) }), "[1,2]")]
169 #[case::nested_arr(Box::new(|ser: &mut AS| {ser.start_array()?.end() }), "[[]]")]
170 #[case::nested_arr_with_el(Box::new(|ser: &mut AS| {let mut n = ser.start_array()?; n.write_u32_value(5) }), "[[5]]")]
171 #[case::nested_arr_first(Box::new(|ser: &mut AS| { ser.start_array()?.end()?; ser.write_u32_value(4) }), "[[],4]")]
172 #[case::nested_arr_last(Box::new(|ser: &mut AS| { ser.write_u32_value(6)?; ser.start_array()?.end() }), "[6,[]]")]
173 #[case::nested_arr_between(Box::new(|ser: &mut AS| { ser.write_u32_value(7)?; ser.start_array()?.end()?; ser.write_u32_value(9) }), "[7,[],9]")]
174 #[case::two_nested_arrays(Box::new(|ser: &mut AS| { ser.start_array()?.end()?; ser.start_array()?.end() }), "[[],[]]")]
175 #[case::nested_obj(Box::new(|ser: &mut AS| ser.start_object()?.end()), "[{}]")]
176 #[case::nested_obj_with_el(Box::new(|ser: &mut AS| { let mut n=ser.start_object()?; n.write_u32_value("a", 3) }), r#"[{"a":3}]"#)]
177 #[case::nested_obj_first(Box::new(|ser: &mut AS| { ser.start_object()?.end()?; ser.write_u32_value(0) }), r#"[{},0]"#)]
178 #[case::nested_obj_last(Box::new(|ser: &mut AS| { ser.write_u32_value(2)?; ser.start_object()?.end() }), r#"[2,{}]"#)]
179 #[case::two_nested_objects(Box::new(|ser: &mut AS| { ser.start_object()?.end()?; ser.start_object()?.end() }), r#"[{},{}]"#)]
180 fn test_array(#[case] code: Box<dyn Fn(&mut AS) -> io::Result<()>>, #[case] expected: &str) -> io::Result<()> {
181 let mut buf = Vec::new();
182 let mut writer = JsonWriter::new_compact(&mut buf);
183 {
184 let mut array_ser = JsonArray::new(&mut writer)?;
185 code(&mut array_ser)?;
186 }
187
188 let actual = String::from_utf8(buf).unwrap();
189 assert_eq!(actual, expected);
190 Ok(())
191 }
192
193 #[rstest]
194 #[case::null(Box::new(|w: &mut AS| w.write_null_value()), "null")]
195 #[case::bool_true(Box::new(|w: &mut AS| w.write_bool_value(true)), "true")]
196 #[case::bool_false(Box::new(|w: &mut AS| w.write_bool_value(false)), "false")]
197 #[case::string(Box::new(|w: &mut AS| w.write_string_value("asdf")), r#""asdf""#)]
198 #[case::string_escaped(Box::new(|w: &mut AS| w.write_string_value("\r\n")), r#""\r\n""#)]
199 #[case::u8(Box::new(|w: &mut AS| w.write_u8_value(2u8)), "2")]
200 #[case::i8(Box::new(|w: &mut AS| w.write_i8_value(-3i8)), "-3")]
201 #[case::u16(Box::new(|w: &mut AS| w.write_u16_value(4u16)), "4")]
202 #[case::i16(Box::new(|w: &mut AS| w.write_i16_value(-5i16)), "-5")]
203 #[case::u32(Box::new(|w: &mut AS| w.write_u32_value(6u32)), "6")]
204 #[case::i32(Box::new(|w: &mut AS| w.write_i32_value(-7i32)), "-7")]
205 #[case::u64(Box::new(|w: &mut AS| w.write_u64_value(8u64)), "8")]
206 #[case::i64(Box::new(|w: &mut AS| w.write_i64_value(-9i64)), "-9")]
207 #[case::u128(Box::new(|w: &mut AS| w.write_u128_value(12u128)), "12")]
208 #[case::i128(Box::new(|w: &mut AS| w.write_i128_value(-13i128)), "-13")]
209 #[case::usize(Box::new(|w: &mut AS| w.write_usize_value(10usize)), "10")]
210 #[case::isize(Box::new(|w: &mut AS| w.write_isize_value(-11isize)), "-11")]
211 #[case::f64(Box::new(|w: &mut AS| w.write_f64_value(2.0)), "2")]
212 #[case::f64_exp_5(Box::new(|w: &mut AS| w.write_f64_value(1.234e5)), "123400")]
213 #[case::f64_exp_10(Box::new(|w: &mut AS| w.write_f64_value(1.234e10)), "1.234e10")]
214 #[case::f64_exp_20(Box::new(|w: &mut AS| w.write_f64_value(1.234e20)), "1.234e20")]
215 #[case::f64_exp_neg_3(Box::new(|w: &mut AS| w.write_f64_value(1.234e-3)), "0.001234")]
216 #[case::f64_exp_neg_10(Box::new(|w: &mut AS| w.write_f64_value(1.234e-10)), "1.234e-10")]
217 #[case::f64_neg(Box::new(|w: &mut AS| w.write_f64_value(-2.0)), "-2")]
218 #[case::f64_neg_exp_5(Box::new(|w: &mut AS| w.write_f64_value(-1.234e5)), "-123400")]
219 #[case::f64_neg_exp_10(Box::new(|w: &mut AS| w.write_f64_value(-1.234e10)), "-1.234e10")]
220 #[case::f64_neg_exp_20(Box::new(|w: &mut AS| w.write_f64_value(-1.234e20)), "-1.234e20")]
221 #[case::f64_neg_exp_neg_3(Box::new(|w: &mut AS| w.write_f64_value(-1.234e-3)), "-0.001234")]
222 #[case::f64_neg_exp_neg_10(Box::new(|w: &mut AS| w.write_f64_value(-1.234e-10)), "-1.234e-10")]
223 #[case::f64_inf(Box::new(|w: &mut AS| w.write_f64_value(f64::INFINITY)), "null")]
224 #[case::f64_neg_inf(Box::new(|w: &mut AS| w.write_f64_value(f64::NEG_INFINITY)), "null")]
225 #[case::f64_nan(Box::new(|w: &mut AS| w.write_f64_value(f64::NAN)), "null")]
226 #[case::f32(Box::new(|w: &mut AS| w.write_f32_value(2.0)), "2")]
227 #[case::f32_exp_5(Box::new(|w: &mut AS| w.write_f32_value(1.234e5)), "123400")]
228 #[case::f32_exp_10(Box::new(|w: &mut AS| w.write_f32_value(1.234e10)), "1.234e10")]
229 #[case::f32_exp_20(Box::new(|w: &mut AS| w.write_f32_value(1.234e20)), "1.234e20")]
230 #[case::f32_exp_neg_3(Box::new(|w: &mut AS| w.write_f32_value(1.234e-3)), "0.001234")]
231 #[case::f32_exp_neg_10(Box::new(|w: &mut AS| w.write_f32_value(1.234e-10)), "1.234e-10")]
232 #[case::f32_neg(Box::new(|w: &mut AS| w.write_f32_value(-2.0)), "-2")]
233 #[case::f32_neg_exp_5(Box::new(|w: &mut AS| w.write_f32_value(-1.234e5)), "-123400")]
234 #[case::f32_neg_exp_10(Box::new(|w: &mut AS| w.write_f32_value(-1.234e10)), "-1.234e10")]
235 #[case::f32_neg_exp_20(Box::new(|w: &mut AS| w.write_f32_value(-1.234e20)), "-1.234e20")]
236 #[case::f32_neg_exp_neg_3(Box::new(|w: &mut AS| w.write_f32_value(-1.234e-3)), "-0.001234")]
237 #[case::f32_neg_exp_neg_10(Box::new(|w: &mut AS| w.write_f32_value(-1.234e-10)), "-1.234e-10")]
238 #[case::f32_inf(Box::new(|w: &mut AS| w.write_f32_value(f32::INFINITY)), "null")]
239 #[case::f32_neg_inf(Box::new(|w: &mut AS| w.write_f32_value(f32::NEG_INFINITY)), "null")]
240 #[case::f32_nan(Box::new(|w: &mut AS| w.write_f32_value(f32::NAN)), "null")]
241 fn test_write_value(#[case] code: Box<dyn Fn(&mut AS) -> io::Result<()>>, #[case] expected: &str) -> io::Result<()> {
242 {
243 let mut buf = Vec::new();
244 let mut writer = JsonWriter::new_compact(&mut buf);
245 {
246 let mut array_ser = JsonArray::new(&mut writer)?;
247 code(&mut array_ser)?;
248 }
249
250 let actual = String::from_utf8(buf).unwrap();
251 let expected = format!("[{}]", expected);
252 assert_eq!(actual, expected);
253 }
254
255 {
257 let mut buf = Vec::new();
258 let mut writer = JsonWriter::new_compact(&mut buf);
259 {
260 let mut array_ser = JsonArray::new(&mut writer)?;
261 array_ser.write_null_value()?;
262 code(&mut array_ser)?;
263 }
264
265 let actual = String::from_utf8(buf).unwrap();
266 let expected = format!("[null,{}]", expected);
267 assert_eq!(actual, expected);
268 }
269
270 Ok(())
271 }
272}