facet_json/
serialize.rs

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