1use std::fmt::Write as FmtWrite;
26
27use crate::error::{Error, Result};
28use serde::ser::{self, Serialize};
29
30pub fn to_string<T: Serialize>(value: &T) -> Result<String> {
59 let mut ser = Serializer::new(0);
60 value.serialize(&mut ser)?;
61 Ok(ser.output)
62}
63
64pub struct Serializer {
73 pub(crate) output: String,
75 indent: usize,
77 is_object: bool,
81}
82
83impl Serializer {
84 fn new(indent: usize) -> Self {
86 Serializer {
87 output: String::new(),
88 indent,
89 is_object: false,
90 }
91 }
92
93 fn pad(&self) -> String {
95 " ".repeat(self.indent)
96 }
97}
98
99fn escape(s: &str) -> Result<String> {
128 let needs_quoting = s.is_empty()
129 || s.starts_with('"')
130 || s.chars()
131 .any(|c| matches!(c, ' ' | '\t' | '\n' | '\r' | '#' | '{' | '}' | '='));
132
133 if needs_quoting && s.contains('"') {
134 return Err(Error::UnsupportedType(
135 "string containing '\"' cannot be represented in quoted form (format has no escape sequences)",
136 ));
137 }
138
139 if needs_quoting {
140 Ok(format!("\"{s}\""))
141 } else {
142 Ok(s.to_owned())
143 }
144}
145
146impl<'a> ser::Serializer for &'a mut Serializer {
151 type Ok = ();
152 type Error = Error;
153
154 type SerializeSeq = SeqSerializer<'a>;
156 type SerializeTuple = SeqSerializer<'a>;
158 type SerializeTupleStruct = SeqSerializer<'a>;
160 type SerializeTupleVariant = SeqSerializer<'a>;
162 type SerializeMap = MapSerializer<'a>;
164 type SerializeStruct = MapSerializer<'a>;
166 type SerializeStructVariant = MapSerializer<'a>;
168
169 fn serialize_bool(self, v: bool) -> Result<()> {
170 self.output.push_str(if v { "true" } else { "false" });
171 Ok(())
172 }
173
174 fn serialize_i8(self, v: i8) -> Result<()> {
175 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
176 }
177
178 fn serialize_i16(self, v: i16) -> Result<()> {
179 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
180 }
181
182 fn serialize_i32(self, v: i32) -> Result<()> {
183 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
184 }
185
186 fn serialize_i64(self, v: i64) -> Result<()> {
187 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
188 }
189
190 fn serialize_u8(self, v: u8) -> Result<()> {
191 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
192 }
193
194 fn serialize_u16(self, v: u16) -> Result<()> {
195 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
196 }
197
198 fn serialize_u32(self, v: u32) -> Result<()> {
199 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
200 }
201
202 fn serialize_u64(self, v: u64) -> Result<()> {
203 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
204 }
205
206 fn serialize_f32(self, v: f32) -> Result<()> {
207 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
208 }
209
210 fn serialize_f64(self, v: f64) -> Result<()> {
211 write!(self.output, "{v}").map_err(|e| Error::Message(e.to_string()))
212 }
213
214 fn serialize_char(self, v: char) -> Result<()> {
215 self.output.push_str(&escape(&v.to_string())?);
217 Ok(())
218 }
219
220 fn serialize_str(self, v: &str) -> Result<()> {
221 self.output.push_str(&escape(v)?);
222 Ok(())
223 }
224
225 fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
226 Err(Error::UnsupportedType("bytes"))
227 }
228
229 fn serialize_none(self) -> Result<()> {
230 self.output.push_str("null");
231 Ok(())
232 }
233
234 fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<()> {
235 value.serialize(self)
236 }
237
238 fn serialize_unit(self) -> Result<()> {
239 self.output.push_str("null");
240 Ok(())
241 }
242
243 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
244 self.serialize_unit()
245 }
246
247 fn serialize_unit_variant(
248 self,
249 _name: &'static str,
250 _index: u32,
251 variant: &'static str,
252 ) -> Result<()> {
253 self.serialize_str(variant)
254 }
255
256 fn serialize_newtype_struct<T: Serialize + ?Sized>(
257 self,
258 _name: &'static str,
259 value: &T,
260 ) -> Result<()> {
261 value.serialize(self)
262 }
263
264 fn serialize_newtype_variant<T: Serialize + ?Sized>(
265 self,
266 _name: &'static str,
267 _index: u32,
268 variant: &'static str,
269 value: &T,
270 ) -> Result<()> {
271 let start_pos = self.output.len();
275 let mut ms = MapSerializer {
276 ser: self,
277 current_key: None,
278 variant_name: None,
279 start_pos,
280 };
281 ms.write_kv(variant, value)
282 }
283
284 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
285 Ok(SeqSerializer {
286 parent: self,
287 items: Vec::new(),
288 variant: None,
289 })
290 }
291
292 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
293 self.serialize_seq(Some(len))
294 }
295
296 fn serialize_tuple_struct(
297 self,
298 _name: &'static str,
299 len: usize,
300 ) -> Result<Self::SerializeTupleStruct> {
301 self.serialize_seq(Some(len))
302 }
303
304 fn serialize_tuple_variant(
305 self,
306 _name: &'static str,
307 _index: u32,
308 variant: &'static str,
309 _len: usize,
310 ) -> Result<Self::SerializeTupleVariant> {
311 Ok(SeqSerializer {
312 parent: self,
313 items: Vec::new(),
314 variant: Some(variant.to_owned()),
315 })
316 }
317
318 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
319 self.is_object = true;
320 let start_pos = self.output.len();
321 Ok(MapSerializer {
322 ser: self,
323 current_key: None,
324 variant_name: None,
325 start_pos,
326 })
327 }
328
329 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
330 self.serialize_map(Some(len))
331 }
332
333 fn serialize_struct_variant(
334 self,
335 _name: &'static str,
336 _index: u32,
337 variant: &'static str,
338 _len: usize,
339 ) -> Result<Self::SerializeStructVariant> {
340 let start_pos = self.output.len();
341 self.indent += 2;
346 Ok(MapSerializer {
347 ser: self,
348 current_key: None,
349 variant_name: Some(variant.to_owned()),
350 start_pos,
351 })
352 }
353}
354
355pub struct SeqSerializer<'a> {
362 parent: &'a mut Serializer,
363 items: Vec<(bool, String)>,
366 variant: Option<String>,
368}
369
370impl ser::SerializeSeq for SeqSerializer<'_> {
371 type Ok = ();
372 type Error = Error;
373
374 fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
375 let mut inner = Serializer::new(0);
376 value.serialize(&mut inner)?;
377 self.items.push((inner.is_object, inner.output));
378 Ok(())
379 }
380
381 fn end(self) -> Result<()> {
382 let pad = self.parent.pad();
383 let inner_pad = " ".repeat(self.parent.indent + 2);
384 let deep_pad = " ".repeat(self.parent.indent + 4);
385 writeln!(self.parent.output, "{{").map_err(|e| Error::Message(e.to_string()))?;
386 for (is_object, item) in &self.items {
387 let trimmed = item.trim_end();
388 if *is_object {
389 writeln!(self.parent.output, "{inner_pad}{{")
392 .map_err(|e| Error::Message(e.to_string()))?;
393 for line in trimmed.lines() {
394 writeln!(self.parent.output, "{deep_pad}{line}")
395 .map_err(|e| Error::Message(e.to_string()))?;
396 }
397 writeln!(self.parent.output, "{inner_pad}}}")
398 .map_err(|e| Error::Message(e.to_string()))?;
399 } else {
400 writeln!(self.parent.output, "{inner_pad}{trimmed}")
402 .map_err(|e| Error::Message(e.to_string()))?;
403 }
404 }
405 writeln!(self.parent.output, "{pad}}}").map_err(|e| Error::Message(e.to_string()))
406 }
407}
408
409impl ser::SerializeTuple for SeqSerializer<'_> {
410 type Ok = ();
411 type Error = Error;
412
413 fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
414 ser::SerializeSeq::serialize_element(self, value)
415 }
416
417 fn end(self) -> Result<()> {
418 ser::SerializeSeq::end(self)
419 }
420}
421
422impl ser::SerializeTupleStruct for SeqSerializer<'_> {
423 type Ok = ();
424 type Error = Error;
425
426 fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
427 ser::SerializeSeq::serialize_element(self, value)
428 }
429
430 fn end(self) -> Result<()> {
431 ser::SerializeSeq::end(self)
432 }
433}
434
435impl ser::SerializeTupleVariant for SeqSerializer<'_> {
436 type Ok = ();
437 type Error = Error;
438
439 fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
440 ser::SerializeSeq::serialize_element(self, value)
441 }
442
443 fn end(self) -> Result<()> {
444 let variant = self.variant.ok_or_else(|| {
447 Error::Message("variant name missing in SerializeTupleVariant::end".into())
448 })?;
449 let pad = self.parent.pad();
450 let inner_pad = " ".repeat(self.parent.indent + 2);
451 let deep_pad = " ".repeat(self.parent.indent + 4);
452 writeln!(self.parent.output, "{pad}{} = {{", escape(&variant)?)
453 .map_err(|e| Error::Message(e.to_string()))?;
454 for (is_object, item) in &self.items {
455 let trimmed = item.trim_end();
456 if *is_object {
457 writeln!(self.parent.output, "{inner_pad}{{")
458 .map_err(|e| Error::Message(e.to_string()))?;
459 for line in trimmed.lines() {
460 writeln!(self.parent.output, "{deep_pad}{line}")
461 .map_err(|e| Error::Message(e.to_string()))?;
462 }
463 writeln!(self.parent.output, "{inner_pad}}}")
464 .map_err(|e| Error::Message(e.to_string()))?;
465 } else {
466 writeln!(self.parent.output, "{inner_pad}{trimmed}")
467 .map_err(|e| Error::Message(e.to_string()))?;
468 }
469 }
470 writeln!(self.parent.output, "{pad}}}").map_err(|e| Error::Message(e.to_string()))
471 }
472}
473
474struct KeySerializer(String);
483
484impl ser::Serializer for &mut KeySerializer {
485 type Ok = ();
486 type Error = Error;
487 type SerializeSeq = ser::Impossible<(), Error>;
488 type SerializeTuple = ser::Impossible<(), Error>;
489 type SerializeTupleStruct = ser::Impossible<(), Error>;
490 type SerializeTupleVariant = ser::Impossible<(), Error>;
491 type SerializeMap = ser::Impossible<(), Error>;
492 type SerializeStruct = ser::Impossible<(), Error>;
493 type SerializeStructVariant = ser::Impossible<(), Error>;
494
495 fn serialize_str(self, v: &str) -> Result<()> {
496 v.clone_into(&mut self.0);
497 Ok(())
498 }
499
500 fn serialize_bool(self, _v: bool) -> Result<()> {
501 Err(Error::KeyMustBeString)
502 }
503 fn serialize_i8(self, _v: i8) -> Result<()> {
504 Err(Error::KeyMustBeString)
505 }
506 fn serialize_i16(self, _v: i16) -> Result<()> {
507 Err(Error::KeyMustBeString)
508 }
509 fn serialize_i32(self, _v: i32) -> Result<()> {
510 Err(Error::KeyMustBeString)
511 }
512 fn serialize_i64(self, _v: i64) -> Result<()> {
513 Err(Error::KeyMustBeString)
514 }
515 fn serialize_u8(self, _v: u8) -> Result<()> {
516 Err(Error::KeyMustBeString)
517 }
518 fn serialize_u16(self, _v: u16) -> Result<()> {
519 Err(Error::KeyMustBeString)
520 }
521 fn serialize_u32(self, _v: u32) -> Result<()> {
522 Err(Error::KeyMustBeString)
523 }
524 fn serialize_u64(self, _v: u64) -> Result<()> {
525 Err(Error::KeyMustBeString)
526 }
527 fn serialize_f32(self, _v: f32) -> Result<()> {
528 Err(Error::KeyMustBeString)
529 }
530 fn serialize_f64(self, _v: f64) -> Result<()> {
531 Err(Error::KeyMustBeString)
532 }
533 fn serialize_char(self, _v: char) -> Result<()> {
534 Err(Error::KeyMustBeString)
535 }
536 fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
537 Err(Error::KeyMustBeString)
538 }
539 fn serialize_none(self) -> Result<()> {
540 Err(Error::KeyMustBeString)
541 }
542 fn serialize_some<T: Serialize + ?Sized>(self, _v: &T) -> Result<()> {
543 Err(Error::KeyMustBeString)
544 }
545 fn serialize_unit(self) -> Result<()> {
546 Err(Error::KeyMustBeString)
547 }
548 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
549 Err(Error::KeyMustBeString)
550 }
551 fn serialize_unit_variant(
552 self,
553 _name: &'static str,
554 _idx: u32,
555 _variant: &'static str,
556 ) -> Result<()> {
557 Err(Error::KeyMustBeString)
558 }
559 fn serialize_newtype_struct<T: Serialize + ?Sized>(
560 self,
561 _name: &'static str,
562 value: &T,
563 ) -> Result<()> {
564 value.serialize(self)
565 }
566 fn serialize_newtype_variant<T: Serialize + ?Sized>(
567 self,
568 _name: &'static str,
569 _idx: u32,
570 _variant: &'static str,
571 _value: &T,
572 ) -> Result<()> {
573 Err(Error::KeyMustBeString)
574 }
575 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
576 Err(Error::KeyMustBeString)
577 }
578 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
579 Err(Error::KeyMustBeString)
580 }
581 fn serialize_tuple_struct(
582 self,
583 _name: &'static str,
584 _len: usize,
585 ) -> Result<Self::SerializeTupleStruct> {
586 Err(Error::KeyMustBeString)
587 }
588 fn serialize_tuple_variant(
589 self,
590 _name: &'static str,
591 _idx: u32,
592 _variant: &'static str,
593 _len: usize,
594 ) -> Result<Self::SerializeTupleVariant> {
595 Err(Error::KeyMustBeString)
596 }
597 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
598 Err(Error::KeyMustBeString)
599 }
600 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
601 Err(Error::KeyMustBeString)
602 }
603 fn serialize_struct_variant(
604 self,
605 _name: &'static str,
606 _idx: u32,
607 _variant: &'static str,
608 _len: usize,
609 ) -> Result<Self::SerializeStructVariant> {
610 Err(Error::KeyMustBeString)
611 }
612}
613
614pub struct MapSerializer<'a> {
621 ser: &'a mut Serializer,
622 current_key: Option<String>,
624 variant_name: Option<String>,
626 start_pos: usize,
630}
631
632impl MapSerializer<'_> {
633 fn write_kv<T: Serialize + ?Sized>(&mut self, key: &str, value: &T) -> Result<()> {
635 let indent = self.ser.indent;
636 let pad = " ".repeat(indent);
637
638 let mut first = Serializer::new(indent);
651 value.serialize(&mut first)?;
652 let rendered = first.output;
653
654 if rendered.contains('\n')
655 && !rendered.trim_start().starts_with('{')
656 && !rendered.trim_start().starts_with('"')
657 {
658 writeln!(self.ser.output, "{pad}{} {{", escape(key)?)
665 .map_err(|e| Error::Message(e.to_string()))?;
666 let mut inner = Serializer::new(indent + 2);
667 value.serialize(&mut inner)?;
668 self.ser.output.push_str(&inner.output);
669 writeln!(self.ser.output, "{pad}}}").map_err(|e| Error::Message(e.to_string()))?;
670 } else if rendered.contains('\n') {
671 writeln!(
676 self.ser.output,
677 "{pad}{} = {}",
678 escape(key)?,
679 rendered.trim_end()
680 )
681 .map_err(|e| Error::Message(e.to_string()))?;
682 } else {
683 let rendered = rendered.trim_end_matches('\n');
685 writeln!(self.ser.output, "{pad}{} = {rendered}", escape(key)?)
686 .map_err(|e| Error::Message(e.to_string()))?;
687 }
688 Ok(())
689 }
690}
691
692impl ser::SerializeMap for MapSerializer<'_> {
693 type Ok = ();
694 type Error = Error;
695
696 fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<()> {
697 let mut ks = KeySerializer(String::new());
698 key.serialize(&mut ks)?;
699 self.current_key = Some(ks.0);
700 Ok(())
701 }
702
703 fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
704 let key = self
705 .current_key
706 .take()
707 .ok_or_else(|| Error::Parse("serialize_value called before serialize_key".into()))?;
708 self.write_kv(&key, value)
709 }
710
711 fn end(self) -> Result<()> {
712 if let Some(variant) = self.variant_name {
713 let pad = " ".repeat(self.ser.indent.saturating_sub(2));
715 let header = format!("{pad}{} {{\n", escape(&variant)?);
716 let footer = format!("{pad}}}\n");
717 self.ser.output.insert_str(self.start_pos, &header);
718 self.ser.output.push_str(&footer);
719 }
720 Ok(())
721 }
722}
723
724impl ser::SerializeStruct for MapSerializer<'_> {
725 type Ok = ();
726 type Error = Error;
727
728 fn serialize_field<T: Serialize + ?Sized>(
729 &mut self,
730 key: &'static str,
731 value: &T,
732 ) -> Result<()> {
733 self.write_kv(key, value)
734 }
735
736 fn end(self) -> Result<()> {
737 ser::SerializeMap::end(self)
738 }
739}
740
741impl ser::SerializeStructVariant for MapSerializer<'_> {
742 type Ok = ();
743 type Error = Error;
744
745 fn serialize_field<T: Serialize + ?Sized>(
746 &mut self,
747 key: &'static str,
748 value: &T,
749 ) -> Result<()> {
750 self.write_kv(key, value)
751 }
752
753 fn end(self) -> Result<()> {
754 ser::SerializeMap::end(self)
755 }
756}