facet_json/
serialize.rs

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