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