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
75pub fn to_string<T>(value: &T) -> Result<String>
82where
83 T: Serialize,
84{
85 to_string_with_style(value, false)
86}
87
88pub 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 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 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 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 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 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}