Skip to main content

clojure_reader/
ser.rs

1use alloc::format;
2use alloc::string::{String, ToString};
3use alloc::vec::Vec;
4use core::fmt::{Display, Write};
5
6use serde::{Serialize, ser};
7
8use crate::error::{Code, Error, Result};
9
10#[derive(Debug)]
11pub struct Serializer {
12  output: String,
13  compound_is_empty: Vec<bool>,
14}
15
16impl Serializer {
17  fn start_compound(&mut self, opener: &str) {
18    self.output += opener;
19    self.compound_is_empty.push(true);
20  }
21
22  fn write_separator(&mut self, separator: &str) -> Result<()> {
23    let compound_is_empty = self
24      .compound_is_empty
25      .last_mut()
26      .ok_or_else(|| ser::Error::custom("serializer compound state missing"))?;
27    if *compound_is_empty {
28      *compound_is_empty = false;
29    } else {
30      self.output += separator;
31    }
32    Ok(())
33  }
34
35  fn end_compound(&mut self, closer: &str) -> Result<()> {
36    self
37      .compound_is_empty
38      .pop()
39      .ok_or_else(|| ser::Error::custom("serializer compound state missing"))?;
40    self.output += closer;
41    Ok(())
42  }
43}
44
45impl ser::Error for Error {
46  #[cold]
47  fn custom<T: Display>(msg: T) -> Self {
48    Self { code: Code::Serde(msg.to_string()), line: None, column: None, ptr: None }
49  }
50}
51
52/// Serializer for creating an EDN formatted String
53///
54/// # Errors
55///
56/// See [`crate::error::Error`].
57/// Always returns `Code::Serde`.
58pub fn to_string<T>(value: &T) -> Result<String>
59where
60  T: Serialize,
61{
62  let mut serializer =
63    Serializer { output: String::with_capacity(128), compound_is_empty: Vec::new() };
64  value.serialize(&mut serializer)?;
65  Ok(serializer.output)
66}
67
68impl ser::Serializer for &mut Serializer {
69  type Ok = ();
70  type Error = Error;
71
72  type SerializeSeq = Self;
73  type SerializeTuple = Self;
74  type SerializeTupleStruct = Self;
75  type SerializeTupleVariant = Self;
76  type SerializeMap = Self;
77  type SerializeStruct = Self;
78  type SerializeStructVariant = Self;
79
80  fn serialize_bool(self, v: bool) -> Result<()> {
81    self.output += if v { "true" } else { "false" };
82    Ok(())
83  }
84
85  // EDN is always an i64 for integers, so all integers will be serialized as i64.
86  fn serialize_i8(self, v: i8) -> Result<()> {
87    self.serialize_i64(i64::from(v))
88  }
89
90  fn serialize_i16(self, v: i16) -> Result<()> {
91    self.serialize_i64(i64::from(v))
92  }
93
94  fn serialize_i32(self, v: i32) -> Result<()> {
95    self.serialize_i64(i64::from(v))
96  }
97
98  fn serialize_i64(self, v: i64) -> Result<()> {
99    // Infallible: String::write_fmt never errors, but handle for correctness.
100    self
101      .output
102      .write_fmt(format_args!("{v}"))
103      .map_err(|e| ser::Error::custom(format!("failed to format {v}: {e}")))?;
104    Ok(())
105  }
106
107  fn serialize_u8(self, v: u8) -> Result<()> {
108    self.serialize_u64(u64::from(v))
109  }
110
111  fn serialize_u16(self, v: u16) -> Result<()> {
112    self.serialize_u64(u64::from(v))
113  }
114
115  fn serialize_u32(self, v: u32) -> Result<()> {
116    self.serialize_u64(u64::from(v))
117  }
118
119  fn serialize_u64(self, v: u64) -> Result<()> {
120    if let Ok(v) = i64::try_from(v) {
121      return self.serialize_i64(v);
122    }
123
124    #[cfg(not(feature = "arbitrary-nums"))]
125    {
126      Err(ser::Error::custom(format!(
127        "can't serialize {v} as a round-trippable EDN integer without arbitrary-nums"
128      )))
129    }
130
131    #[cfg(feature = "arbitrary-nums")]
132    {
133      // Infallible: String::write_fmt never errors, but handle for correctness.
134      self
135        .output
136        .write_fmt(format_args!("{v}N"))
137        .map_err(|e| ser::Error::custom(format!("failed to format {v}: {e}")))?;
138      Ok(())
139    }
140  }
141
142  fn serialize_f32(self, v: f32) -> Result<()> {
143    self.serialize_f64(f64::from(v))
144  }
145
146  fn serialize_f64(self, v: f64) -> Result<()> {
147    // Infallible: String::write_fmt never errors, but handle for correctness.
148    self
149      .output
150      .write_fmt(format_args!("{v}"))
151      .map_err(|e| ser::Error::custom(format!("failed to format {v}: {e}")))?;
152    Ok(())
153  }
154
155  fn serialize_char(self, v: char) -> Result<()> {
156    self.output += "\\";
157    if let Some(c) = crate::edn::char_to_edn(v) {
158      self.output += c;
159    } else {
160      self.output.push(v);
161    }
162    Ok(())
163  }
164
165  fn serialize_str(self, v: &str) -> Result<()> {
166    self.output += "\"";
167    self.output += v;
168    self.output += "\"";
169    Ok(())
170  }
171
172  // as of 2024-11, this is not called by serde
173  // https://serde.rs/impl-serialize.html
174  fn serialize_bytes(self, v: &[u8]) -> Result<()> {
175    use serde::ser::SerializeSeq;
176
177    let mut seq = self.serialize_seq(Some(v.len()))?;
178    for byte in v {
179      seq.serialize_element(byte)?;
180    }
181    seq.end()
182  }
183
184  fn serialize_none(self) -> Result<()> {
185    self.serialize_unit()
186  }
187
188  fn serialize_some<T>(self, value: &T) -> Result<()>
189  where
190    T: ?Sized + Serialize,
191  {
192    value.serialize(self)
193  }
194
195  fn serialize_unit(self) -> Result<()> {
196    self.output += "nil";
197    Ok(())
198  }
199
200  fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
201    self.serialize_unit()
202  }
203
204  fn serialize_unit_variant(
205    self,
206    name: &'static str,
207    _variant_index: u32,
208    variant: &'static str,
209  ) -> Result<()> {
210    self.output += "#";
211    self.output += name;
212    self.output += "/";
213    self.output += variant;
214    self.output += " ";
215    self.serialize_unit()
216  }
217
218  fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
219  where
220    T: ?Sized + Serialize,
221  {
222    value.serialize(self)
223  }
224
225  fn serialize_newtype_variant<T>(
226    self,
227    name: &'static str,
228    _variant_index: u32,
229    variant: &'static str,
230    value: &T,
231  ) -> Result<()>
232  where
233    T: ?Sized + Serialize,
234  {
235    self.output += "#";
236    self.output += name;
237    self.output += "/";
238    self.output += variant;
239    self.output += " ";
240    value.serialize(self)
241  }
242
243  fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
244    if let Some(len) = len {
245      self.output.reserve(len * 16);
246    }
247    self.start_compound("[");
248    Ok(self)
249  }
250
251  fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
252    self.start_compound("[");
253    Ok(self)
254  }
255
256  fn serialize_tuple_struct(
257    self,
258    _name: &'static str,
259    len: usize,
260  ) -> Result<Self::SerializeTupleStruct> {
261    self.serialize_tuple(len)
262  }
263
264  fn serialize_tuple_variant(
265    self,
266    name: &'static str,
267    _variant_index: u32,
268    variant: &'static str,
269    _len: usize,
270  ) -> Result<Self::SerializeTupleVariant> {
271    self.output += "#";
272    self.output += name;
273    self.output += "/";
274    self.output += variant;
275    self.output += " ";
276    self.start_compound("[");
277    Ok(self)
278  }
279
280  fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
281    if let Some(len) = len {
282      self.output.reserve(len * 32);
283    }
284    self.start_compound("{");
285    Ok(self)
286  }
287
288  fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
289    self.serialize_map(Some(len))
290  }
291
292  fn serialize_struct_variant(
293    self,
294    name: &'static str,
295    _variant_index: u32,
296    variant: &'static str,
297    _len: usize,
298  ) -> Result<Self::SerializeStructVariant> {
299    self.output += "#";
300    self.output += name;
301    self.output += "/";
302    self.output += variant;
303    self.output += " ";
304    self.start_compound("{");
305    Ok(self)
306  }
307}
308
309impl ser::SerializeSeq for &mut Serializer {
310  type Ok = ();
311  type Error = Error;
312
313  fn serialize_element<T>(&mut self, value: &T) -> Result<()>
314  where
315    T: ?Sized + Serialize,
316  {
317    self.write_separator(" ")?;
318    value.serialize(&mut **self)
319  }
320
321  fn end(self) -> Result<()> {
322    self.end_compound("]")
323  }
324}
325
326impl ser::SerializeTuple for &mut Serializer {
327  type Ok = ();
328  type Error = Error;
329
330  fn serialize_element<T>(&mut self, value: &T) -> Result<()>
331  where
332    T: ?Sized + Serialize,
333  {
334    self.write_separator(" ")?;
335    value.serialize(&mut **self)
336  }
337
338  fn end(self) -> Result<()> {
339    self.end_compound("]")
340  }
341}
342
343impl ser::SerializeTupleStruct for &mut Serializer {
344  type Ok = ();
345  type Error = Error;
346
347  fn serialize_field<T>(&mut self, value: &T) -> Result<()>
348  where
349    T: ?Sized + Serialize,
350  {
351    self.write_separator(" ")?;
352    value.serialize(&mut **self)
353  }
354
355  fn end(self) -> Result<()> {
356    self.end_compound("]")
357  }
358}
359
360impl ser::SerializeTupleVariant for &mut Serializer {
361  type Ok = ();
362  type Error = Error;
363
364  fn serialize_field<T>(&mut self, value: &T) -> Result<()>
365  where
366    T: ?Sized + Serialize,
367  {
368    self.write_separator(" ")?;
369    value.serialize(&mut **self)
370  }
371
372  fn end(self) -> Result<()> {
373    self.end_compound("]")
374  }
375}
376
377impl ser::SerializeMap for &mut Serializer {
378  type Ok = ();
379  type Error = Error;
380
381  fn serialize_key<T>(&mut self, key: &T) -> Result<()>
382  where
383    T: ?Sized + Serialize,
384  {
385    self.write_separator(", ")?;
386
387    key.serialize(&mut **self)
388  }
389
390  fn serialize_value<T>(&mut self, value: &T) -> Result<()>
391  where
392    T: ?Sized + Serialize,
393  {
394    self.output += " ";
395    value.serialize(&mut **self)
396  }
397
398  fn end(self) -> Result<()> {
399    self.end_compound("}")
400  }
401}
402
403impl ser::SerializeStruct for &mut Serializer {
404  type Ok = ();
405  type Error = Error;
406
407  fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
408  where
409    T: ?Sized + Serialize,
410  {
411    self.write_separator(", ")?;
412    self.output += ":";
413    self.output += key;
414    self.output += " ";
415    value.serialize(&mut **self)
416  }
417
418  fn end(self) -> Result<()> {
419    self.end_compound("}")
420  }
421}
422
423impl ser::SerializeStructVariant for &mut Serializer {
424  type Ok = ();
425  type Error = Error;
426
427  fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
428  where
429    T: ?Sized + Serialize,
430  {
431    self.write_separator(", ")?;
432    self.output += ":";
433    self.output += key;
434    self.output += " ";
435    value.serialize(&mut **self)
436  }
437
438  fn end(self) -> Result<()> {
439    self.end_compound("}")
440  }
441}