facet_json/
json_serializer.rs

1use facet_serialize::Serializer;
2use log::debug;
3use std::io::{self, Write};
4
5#[derive(Debug)]
6enum StackItem {
7    ArrayItem { first: bool },
8    ObjectItem { object_state: ObjectItemState },
9}
10
11#[derive(Debug)]
12enum ObjectItemState {
13    FirstKey,
14    Key,
15    Value,
16}
17
18/// A serializer for JSON format that implements the `facet_serialize::Serializer` trait.
19pub struct JsonSerializer<W> {
20    writer: W,
21    stack: Vec<StackItem>,
22}
23
24impl<W> JsonSerializer<W>
25where
26    W: Write,
27{
28    /// Creates a new JSON serializer with the given writer.
29    pub fn new(writer: W) -> Self {
30        Self {
31            writer,
32            stack: Vec::new(),
33        }
34    }
35
36    fn start_value(&mut self) -> Result<(), io::Error> {
37        debug!("start_value, stack = {:?}", self.stack);
38
39        match self.stack.last_mut() {
40            Some(StackItem::ArrayItem { first }) => {
41                if *first {
42                    *first = false;
43                } else {
44                    write!(self.writer, ",")?;
45                }
46            }
47            Some(StackItem::ObjectItem { object_state }) => {
48                debug!("ObjectItem: object_state = {:?}", object_state);
49                match object_state {
50                    ObjectItemState::FirstKey => {
51                        *object_state = ObjectItemState::Value;
52                    }
53                    ObjectItemState::Key => {
54                        write!(self.writer, ",")?;
55                        *object_state = ObjectItemState::Value;
56                    }
57                    ObjectItemState::Value => {
58                        write!(self.writer, ":")?;
59                        *object_state = ObjectItemState::Key;
60                    }
61                }
62            }
63            None => {
64                debug!("No stack frame (top-level value)");
65            }
66        }
67
68        Ok(())
69    }
70
71    fn end_value(&mut self) -> Result<(), io::Error> {
72        Ok(())
73    }
74}
75
76impl<W> Serializer for JsonSerializer<W>
77where
78    W: Write,
79{
80    type Error = io::Error;
81
82    fn serialize_u8(&mut self, value: u8) -> Result<(), Self::Error> {
83        self.start_value()?;
84        write!(self.writer, "{}", value)?;
85        self.end_value()
86    }
87
88    fn serialize_u16(&mut self, value: u16) -> Result<(), Self::Error> {
89        self.start_value()?;
90        write!(self.writer, "{}", value)?;
91        self.end_value()
92    }
93
94    fn serialize_u32(&mut self, value: u32) -> Result<(), Self::Error> {
95        self.start_value()?;
96        write!(self.writer, "{}", value)?;
97        self.end_value()
98    }
99
100    fn serialize_u64(&mut self, value: u64) -> Result<(), Self::Error> {
101        self.start_value()?;
102        write!(self.writer, "{}", value)?;
103        self.end_value()
104    }
105
106    fn serialize_u128(&mut self, value: u128) -> Result<(), Self::Error> {
107        self.start_value()?;
108        write!(self.writer, "{}", value)?;
109        self.end_value()
110    }
111
112    fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error> {
113        self.start_value()?;
114        write!(self.writer, "{}", value)?;
115        self.end_value()
116    }
117
118    fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error> {
119        self.start_value()?;
120        write!(self.writer, "{}", value)?;
121        self.end_value()
122    }
123
124    fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error> {
125        self.start_value()?;
126        write!(self.writer, "{}", value)?;
127        self.end_value()
128    }
129
130    fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error> {
131        self.start_value()?;
132        write!(self.writer, "{}", value)?;
133        self.end_value()
134    }
135
136    fn serialize_i64(&mut self, value: i64) -> Result<(), Self::Error> {
137        self.start_value()?;
138        write!(self.writer, "{}", value)?;
139        self.end_value()
140    }
141
142    fn serialize_i128(&mut self, value: i128) -> Result<(), Self::Error> {
143        self.start_value()?;
144        write!(self.writer, "{}", value)?;
145        self.end_value()
146    }
147
148    fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error> {
149        self.start_value()?;
150        write!(self.writer, "{}", value)?;
151        self.end_value()
152    }
153
154    fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error> {
155        self.start_value()?;
156        write!(self.writer, "{}", value)?;
157        self.end_value()
158    }
159
160    fn serialize_f64(&mut self, value: f64) -> Result<(), Self::Error> {
161        self.start_value()?;
162        write!(self.writer, "{}", value)?;
163        self.end_value()
164    }
165
166    fn serialize_bool(&mut self, value: bool) -> Result<(), Self::Error> {
167        self.start_value()?;
168        write!(self.writer, "{}", if value { "true" } else { "false" })?;
169        self.end_value()
170    }
171
172    fn serialize_char(&mut self, value: char) -> Result<(), Self::Error> {
173        self.start_value()?;
174        self.writer.write_all(b"\"")?;
175        write_json_escaped_char(&mut self.writer, value)?;
176        self.writer.write_all(b"\"")?;
177        self.end_value()
178    }
179
180    fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error> {
181        self.start_value()?;
182        write_json_string(&mut self.writer, value)?;
183        self.end_value()
184    }
185
186    fn serialize_bytes(&mut self, _value: &[u8]) -> Result<(), Self::Error> {
187        panic!("JSON does not support byte arrays")
188    }
189
190    fn serialize_none(&mut self) -> Result<(), Self::Error> {
191        self.start_value()?;
192        self.writer.write_all(b"null")?;
193        self.end_value()
194    }
195
196    fn serialize_unit(&mut self) -> Result<(), Self::Error> {
197        self.start_value()?;
198        self.writer.write_all(b"null")?;
199        self.end_value()
200    }
201
202    fn serialize_unit_variant(
203        &mut self,
204        _variant_index: usize,
205        variant_name: &'static str,
206    ) -> Result<(), Self::Error> {
207        self.start_value()?;
208        write_json_string(&mut self.writer, variant_name)?;
209        self.end_value()
210    }
211
212    fn start_object(&mut self, _len: Option<usize>) -> Result<(), Self::Error> {
213        self.start_value()?;
214        self.writer.write_all(b"{")?;
215        self.stack.push(StackItem::ObjectItem {
216            object_state: ObjectItemState::FirstKey,
217        });
218        Ok(())
219    }
220
221    fn end_object(&mut self) -> Result<(), Self::Error> {
222        let object = self.stack.pop().unwrap();
223        match object {
224            StackItem::ArrayItem { .. } => unreachable!(),
225            StackItem::ObjectItem { object_state } => match object_state {
226                ObjectItemState::FirstKey | ObjectItemState::Key => {
227                    // good
228                }
229                ObjectItemState::Value => unreachable!(),
230            },
231        }
232        self.writer.write_all(b"}")?;
233        self.end_value()?;
234        Ok(())
235    }
236
237    fn start_array(&mut self, _len: Option<usize>) -> Result<(), Self::Error> {
238        self.start_value()?;
239        self.writer.write_all(b"[")?;
240        self.stack.push(StackItem::ArrayItem { first: true });
241        Ok(())
242    }
243
244    fn end_array(&mut self) -> Result<(), Self::Error> {
245        let item = self.stack.pop().unwrap();
246        match item {
247            StackItem::ArrayItem { .. } => {
248                // good
249            }
250            StackItem::ObjectItem { .. } => unreachable!(),
251        }
252        self.writer.write_all(b"]")?;
253        self.end_value()?;
254        Ok(())
255    }
256
257    fn start_map(&mut self, _len: Option<usize>) -> Result<(), Self::Error> {
258        self.start_object(_len)
259    }
260
261    fn end_map(&mut self) -> Result<(), Self::Error> {
262        self.end_object()
263    }
264
265    fn serialize_field_name(&mut self, name: &'static str) -> Result<(), Self::Error> {
266        // Handle object key comma logic
267        if let Some(StackItem::ObjectItem { object_state }) = self.stack.last_mut() {
268            match object_state {
269                ObjectItemState::FirstKey => {
270                    *object_state = ObjectItemState::Key;
271                }
272                ObjectItemState::Key => {
273                    self.writer.write_all(b",")?;
274                }
275                ObjectItemState::Value => unreachable!(),
276            }
277        }
278        write_json_string(&mut self.writer, name)?;
279        if let Some(StackItem::ObjectItem { object_state }) = self.stack.last_mut() {
280            *object_state = ObjectItemState::Value;
281        }
282        Ok(())
283    }
284}
285
286/// Properly escapes and writes a JSON string
287fn write_json_string<W: Write>(writer: &mut W, s: &str) -> io::Result<()> {
288    writer.write_all(b"\"")?;
289
290    for c in s.chars() {
291        write_json_escaped_char(writer, c)?;
292    }
293
294    writer.write_all(b"\"")
295}
296
297/// Writes a single JSON escaped character
298fn write_json_escaped_char<W: Write>(writer: &mut W, c: char) -> io::Result<()> {
299    match c {
300        '"' => writer.write_all(b"\\\""),
301        '\\' => writer.write_all(b"\\\\"),
302        '\n' => writer.write_all(b"\\n"),
303        '\r' => writer.write_all(b"\\r"),
304        '\t' => writer.write_all(b"\\t"),
305        '\u{08}' => writer.write_all(b"\\b"),
306        '\u{0C}' => writer.write_all(b"\\f"),
307        c if c.is_control() => {
308            let mut buf = [0; 6];
309            let s = format!("{:04x}", c as u32);
310            buf[0] = b'\\';
311            buf[1] = b'u';
312            buf[2] = s.as_bytes()[0];
313            buf[3] = s.as_bytes()[1];
314            buf[4] = s.as_bytes()[2];
315            buf[5] = s.as_bytes()[3];
316            writer.write_all(&buf)
317        }
318        c => {
319            let mut buf = [0; 4];
320            let len = c.encode_utf8(&mut buf).len();
321            writer.write_all(&buf[..len])
322        }
323    }
324}