1use serde::{Serialize, ser};
4
5use crate::error::{Error, Result};
6
7pub struct Serializer {
9 output: String,
10 indent_level: usize,
11 indent_size: usize,
12}
13
14impl Serializer {
15 fn new() -> Self {
16 Serializer {
17 output: String::new(),
18 indent_level: 0,
19 indent_size: 2,
20 }
21 }
22
23 fn indent(&mut self) {
24 self.indent_level += 1;
25 }
26
27 fn dedent(&mut self) {
28 self.indent_level = self.indent_level.saturating_sub(1);
29 }
30
31 fn write_indent(&mut self) {
32 for _ in 0..(self.indent_level * self.indent_size) {
33 self.output.push(' ');
34 }
35 }
36}
37
38pub fn to_string<T>(value: &T) -> Result<String>
40where
41 T: Serialize,
42{
43 let mut serializer = Serializer::new();
44 value.serialize(&mut serializer)?;
45 Ok(serializer.output)
46}
47
48impl<'a> ser::Serializer for &'a mut Serializer {
49 type Ok = ();
50 type Error = Error;
51
52 type SerializeSeq = Self;
53 type SerializeTuple = Self;
54 type SerializeTupleStruct = Self;
55 type SerializeTupleVariant = Self;
56 type SerializeMap = Self;
57 type SerializeStruct = Self;
58 type SerializeStructVariant = Self;
59
60 fn serialize_bool(self, v: bool) -> Result<()> {
61 self.output += if v { "true" } else { "false" };
62 Ok(())
63 }
64
65 fn serialize_i8(self, v: i8) -> Result<()> {
66 self.serialize_i32(i32::from(v))
67 }
68
69 fn serialize_i16(self, v: i16) -> Result<()> {
70 self.serialize_i32(i32::from(v))
71 }
72
73 fn serialize_i32(self, v: i32) -> Result<()> {
74 self.output += &v.to_string();
75 Ok(())
76 }
77
78 fn serialize_i64(self, v: i64) -> Result<()> {
79 self.output += &v.to_string();
80 self.output += "L";
81 Ok(())
82 }
83
84 fn serialize_u8(self, v: u8) -> Result<()> {
85 self.serialize_u32(u32::from(v))
86 }
87
88 fn serialize_u16(self, v: u16) -> Result<()> {
89 self.serialize_u32(u32::from(v))
90 }
91
92 fn serialize_u32(self, v: u32) -> Result<()> {
93 self.output += &v.to_string();
94 Ok(())
95 }
96
97 fn serialize_u64(self, v: u64) -> Result<()> {
98 self.output += &v.to_string();
99 self.output += "L";
100 Ok(())
101 }
102
103 fn serialize_f32(self, v: f32) -> Result<()> {
104 self.serialize_f64(f64::from(v))
105 }
106
107 fn serialize_f64(self, v: f64) -> Result<()> {
108 let s = v.to_string();
109 self.output += &s;
110 if !s.contains('.') && !s.contains('e') && !s.contains('E') {
112 self.output += ".0";
113 }
114 Ok(())
115 }
116
117 fn serialize_char(self, v: char) -> Result<()> {
118 self.serialize_str(&v.to_string())
119 }
120
121 fn serialize_str(self, v: &str) -> Result<()> {
122 self.output.push('"');
123 for ch in v.chars() {
124 match ch {
125 '"' => self.output.push_str("\\\""),
126 '\\' => self.output.push_str("\\\\"),
127 '\n' => self.output.push_str("\\n"),
128 '\r' => self.output.push_str("\\r"),
129 '\t' => self.output.push_str("\\t"),
130 '\x0C' => self.output.push_str("\\f"),
131 '\x08' => self.output.push_str("\\b"),
132 '\x0B' => self.output.push_str("\\v"),
133 '\x07' => self.output.push_str("\\a"),
134 _ => self.output.push(ch),
135 }
136 }
137 self.output.push('"');
138 Ok(())
139 }
140
141 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
142 use ser::SerializeSeq;
143 let mut seq = self.serialize_seq(Some(v.len()))?;
144 for byte in v {
145 seq.serialize_element(byte)?;
146 }
147 seq.end()
148 }
149
150 fn serialize_none(self) -> Result<()> {
151 Err(Error::TypeNotSupported("Option::None".to_string()))
152 }
153
154 fn serialize_some<T>(self, value: &T) -> Result<()>
155 where
156 T: ?Sized + Serialize,
157 {
158 value.serialize(self)
159 }
160
161 fn serialize_unit(self) -> Result<()> {
162 Err(Error::UnitNotSupported)
163 }
164
165 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
166 self.serialize_unit()
167 }
168
169 fn serialize_unit_variant(
170 self,
171 _name: &'static str,
172 _variant_index: u32,
173 variant: &'static str,
174 ) -> Result<()> {
175 self.serialize_str(variant)
176 }
177
178 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
179 where
180 T: ?Sized + Serialize,
181 {
182 value.serialize(self)
183 }
184
185 fn serialize_newtype_variant<T>(
186 self,
187 _name: &'static str,
188 _variant_index: u32,
189 variant: &'static str,
190 value: &T,
191 ) -> Result<()>
192 where
193 T: ?Sized + Serialize,
194 {
195 self.output += variant;
196 self.output += " = ";
197 value.serialize(&mut *self)?;
198 Ok(())
199 }
200
201 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
202 self.output.push('[');
203 Ok(self)
204 }
205
206 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
207 self.output.push('(');
208 Ok(self)
209 }
210
211 fn serialize_tuple_struct(
212 self,
213 _name: &'static str,
214 _len: usize,
215 ) -> Result<Self::SerializeTupleStruct> {
216 self.output.push('(');
217 Ok(self)
218 }
219
220 fn serialize_tuple_variant(
221 self,
222 _name: &'static str,
223 _variant_index: u32,
224 variant: &'static str,
225 _len: usize,
226 ) -> Result<Self::SerializeTupleVariant> {
227 self.output += variant;
228 self.output += " = (";
229 Ok(self)
230 }
231
232 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
233 self.output.push('{');
234 self.indent();
235 Ok(self)
236 }
237
238 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
239 self.serialize_map(Some(len))
240 }
241
242 fn serialize_struct_variant(
243 self,
244 _name: &'static str,
245 _variant_index: u32,
246 variant: &'static str,
247 _len: usize,
248 ) -> Result<Self::SerializeStructVariant> {
249 self.output += variant;
250 self.output += " = {";
251 self.indent();
252 Ok(self)
253 }
254}
255
256impl<'a> ser::SerializeSeq for &'a mut Serializer {
257 type Ok = ();
258 type Error = Error;
259
260 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
261 where
262 T: ?Sized + Serialize,
263 {
264 if !self.output.ends_with('[') {
265 self.output += ", ";
266 }
267 value.serialize(&mut **self)
268 }
269
270 fn end(self) -> Result<()> {
271 self.output.push(']');
272 Ok(())
273 }
274}
275
276impl<'a> ser::SerializeTuple for &'a mut Serializer {
277 type Ok = ();
278 type Error = Error;
279
280 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
281 where
282 T: ?Sized + Serialize,
283 {
284 if !self.output.ends_with('(') {
285 self.output += ", ";
286 }
287 value.serialize(&mut **self)
288 }
289
290 fn end(self) -> Result<()> {
291 self.output.push(')');
292 Ok(())
293 }
294}
295
296impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
297 type Ok = ();
298 type Error = Error;
299
300 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
301 where
302 T: ?Sized + Serialize,
303 {
304 if !self.output.ends_with('(') {
305 self.output += ", ";
306 }
307 value.serialize(&mut **self)
308 }
309
310 fn end(self) -> Result<()> {
311 self.output.push(')');
312 Ok(())
313 }
314}
315
316impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
317 type Ok = ();
318 type Error = Error;
319
320 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
321 where
322 T: ?Sized + Serialize,
323 {
324 if !self.output.ends_with('(') {
325 self.output += ", ";
326 }
327 value.serialize(&mut **self)
328 }
329
330 fn end(self) -> Result<()> {
331 self.output.push(')');
332 Ok(())
333 }
334}
335
336impl<'a> ser::SerializeMap for &'a mut Serializer {
337 type Ok = ();
338 type Error = Error;
339
340 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
341 where
342 T: ?Sized + Serialize,
343 {
344 if !self.output.ends_with('{') {
345 self.output.push(';');
346 }
347 self.output.push('\n');
348 self.write_indent();
349 let mut key_capture = KeyCapture { key: String::new() };
351 key.serialize(&mut key_capture)?;
352 self.output += &key_capture.key;
353 Ok(())
354 }
355
356 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
357 where
358 T: ?Sized + Serialize,
359 {
360 self.output += " = ";
361 value.serialize(&mut **self)
362 }
363
364 fn end(self) -> Result<()> {
365 self.dedent();
366 if !self.output.ends_with('{') {
367 self.output.push(';');
368 }
369 self.output.push('\n');
370 self.write_indent();
371 self.output.push('}');
372 Ok(())
373 }
374}
375
376impl<'a> ser::SerializeStruct for &'a mut Serializer {
377 type Ok = ();
378 type Error = Error;
379
380 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
381 where
382 T: ?Sized + Serialize,
383 {
384 if !self.output.ends_with('{') {
385 self.output.push(';');
386 }
387 self.output.push('\n');
388 self.write_indent();
389 self.output += key;
390 self.output += " = ";
391 value.serialize(&mut **self)
392 }
393
394 fn end(self) -> Result<()> {
395 self.dedent();
396 if !self.output.ends_with('{') {
397 self.output.push(';');
398 }
399 self.output.push('\n');
400 self.write_indent();
401 self.output.push('}');
402 Ok(())
403 }
404}
405
406impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
407 type Ok = ();
408 type Error = Error;
409
410 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
411 where
412 T: ?Sized + Serialize,
413 {
414 if !self.output.ends_with('{') {
415 self.output.push(';');
416 }
417 self.output.push('\n');
418 self.write_indent();
419 self.output += key;
420 self.output += " = ";
421 value.serialize(&mut **self)
422 }
423
424 fn end(self) -> Result<()> {
425 self.dedent();
426 if !self.output.ends_with('{') {
427 self.output.push(';');
428 }
429 self.output.push('\n');
430 self.write_indent();
431 self.output.push('}');
432 Ok(())
433 }
434}
435
436struct KeyCapture {
438 key: String,
439}
440
441impl<'a> ser::Serializer for &'a mut KeyCapture {
442 type Ok = ();
443 type Error = Error;
444
445 type SerializeSeq = ser::Impossible<(), Error>;
446 type SerializeTuple = ser::Impossible<(), Error>;
447 type SerializeTupleStruct = ser::Impossible<(), Error>;
448 type SerializeTupleVariant = ser::Impossible<(), Error>;
449 type SerializeMap = ser::Impossible<(), Error>;
450 type SerializeStruct = ser::Impossible<(), Error>;
451 type SerializeStructVariant = ser::Impossible<(), Error>;
452
453 fn serialize_str(self, v: &str) -> Result<()> {
454 self.key = v.to_string();
455 Ok(())
456 }
457
458 fn serialize_unit_variant(
459 self,
460 _name: &'static str,
461 _variant_index: u32,
462 variant: &'static str,
463 ) -> Result<()> {
464 self.key = variant.to_string();
465 Ok(())
466 }
467
468 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
469 where
470 T: ?Sized + Serialize,
471 {
472 value.serialize(self)
473 }
474
475 fn serialize_bool(self, _v: bool) -> Result<()> {
476 Err(Error::KeyMustBeAString)
477 }
478
479 fn serialize_i8(self, _v: i8) -> Result<()> {
480 Err(Error::KeyMustBeAString)
481 }
482
483 fn serialize_i16(self, _v: i16) -> Result<()> {
484 Err(Error::KeyMustBeAString)
485 }
486
487 fn serialize_i32(self, _v: i32) -> Result<()> {
488 Err(Error::KeyMustBeAString)
489 }
490
491 fn serialize_i64(self, _v: i64) -> Result<()> {
492 Err(Error::KeyMustBeAString)
493 }
494
495 fn serialize_u8(self, _v: u8) -> Result<()> {
496 Err(Error::KeyMustBeAString)
497 }
498
499 fn serialize_u16(self, _v: u16) -> Result<()> {
500 Err(Error::KeyMustBeAString)
501 }
502
503 fn serialize_u32(self, _v: u32) -> Result<()> {
504 Err(Error::KeyMustBeAString)
505 }
506
507 fn serialize_u64(self, _v: u64) -> Result<()> {
508 Err(Error::KeyMustBeAString)
509 }
510
511 fn serialize_f32(self, _v: f32) -> Result<()> {
512 Err(Error::KeyMustBeAString)
513 }
514
515 fn serialize_f64(self, _v: f64) -> Result<()> {
516 Err(Error::KeyMustBeAString)
517 }
518
519 fn serialize_char(self, _v: char) -> Result<()> {
520 Err(Error::KeyMustBeAString)
521 }
522
523 fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
524 Err(Error::KeyMustBeAString)
525 }
526
527 fn serialize_none(self) -> Result<()> {
528 Err(Error::KeyMustBeAString)
529 }
530
531 fn serialize_some<T>(self, _value: &T) -> Result<()>
532 where
533 T: ?Sized + Serialize,
534 {
535 Err(Error::KeyMustBeAString)
536 }
537
538 fn serialize_unit(self) -> Result<()> {
539 Err(Error::KeyMustBeAString)
540 }
541
542 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
543 Err(Error::KeyMustBeAString)
544 }
545
546 fn serialize_newtype_variant<T>(
547 self,
548 _name: &'static str,
549 _variant_index: u32,
550 _variant: &'static str,
551 _value: &T,
552 ) -> Result<()>
553 where
554 T: ?Sized + Serialize,
555 {
556 Err(Error::KeyMustBeAString)
557 }
558
559 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
560 Err(Error::KeyMustBeAString)
561 }
562
563 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
564 Err(Error::KeyMustBeAString)
565 }
566
567 fn serialize_tuple_struct(
568 self,
569 _name: &'static str,
570 _len: usize,
571 ) -> Result<Self::SerializeTupleStruct> {
572 Err(Error::KeyMustBeAString)
573 }
574
575 fn serialize_tuple_variant(
576 self,
577 _name: &'static str,
578 _variant_index: u32,
579 _variant: &'static str,
580 _len: usize,
581 ) -> Result<Self::SerializeTupleVariant> {
582 Err(Error::KeyMustBeAString)
583 }
584
585 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
586 Err(Error::KeyMustBeAString)
587 }
588
589 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
590 Err(Error::KeyMustBeAString)
591 }
592
593 fn serialize_struct_variant(
594 self,
595 _name: &'static str,
596 _variant_index: u32,
597 _variant: &'static str,
598 _len: usize,
599 ) -> Result<Self::SerializeStructVariant> {
600 Err(Error::KeyMustBeAString)
601 }
602}
603
604#[cfg(test)]
605mod tests {
606 use super::*;
607 use serde::Serialize;
608
609 #[test]
610 fn test_serialize_primitives() {
611 assert_eq!(to_string(&42u32).unwrap(), "42");
612 assert_eq!(to_string(&42i64).unwrap(), "42L");
613 assert_eq!(to_string(&3.14f64).unwrap(), "3.14");
614 assert_eq!(to_string(&true).unwrap(), "true");
615 assert_eq!(to_string(&"hello".to_string()).unwrap(), "\"hello\"");
616 }
617
618 #[test]
619 fn test_serialize_array() {
620 let arr = vec![1, 2, 3];
621 assert_eq!(to_string(&arr).unwrap(), "[1, 2, 3]");
622 }
623
624 #[test]
625 fn test_serialize_struct() {
626 #[derive(Serialize)]
627 struct Test {
628 a: i32,
629 b: String,
630 }
631
632 let test = Test {
633 a: 42,
634 b: "hello".to_string(),
635 };
636 let result = to_string(&test).unwrap();
637 assert!(result.contains("a = 42"));
638 assert!(result.contains("b = \"hello\""));
639 }
640
641 #[test]
642 fn test_serialize_i8_no_l_suffix() {
643 assert_eq!(to_string(&42i8).unwrap(), "42");
644 assert_eq!(to_string(&42i16).unwrap(), "42");
645 assert_eq!(to_string(&42i32).unwrap(), "42");
646 assert_eq!(to_string(&42i64).unwrap(), "42L");
647 }
648
649 #[test]
650 fn test_serialize_u64_has_l_suffix() {
651 assert_eq!(to_string(&42u8).unwrap(), "42");
652 assert_eq!(to_string(&42u16).unwrap(), "42");
653 assert_eq!(to_string(&42u32).unwrap(), "42");
654 assert_eq!(to_string(&42u64).unwrap(), "42L");
655 }
656
657 #[test]
658 fn test_serialize_float_always_has_decimal() {
659 assert_eq!(to_string(&1.0f64).unwrap(), "1.0");
661 assert_eq!(to_string(&0.0f64).unwrap(), "0.0");
662 assert_eq!(to_string(&3.14f64).unwrap(), "3.14");
664 }
665
666 #[test]
667 fn test_serialize_tuple_as_list() {
668 let tup = (1, 2, 3);
669 assert_eq!(to_string(&tup).unwrap(), "(1, 2, 3)");
670 }
671
672 #[test]
673 fn test_serialize_map_bare_keys() {
674 use indexmap::IndexMap;
675 let mut map = IndexMap::new();
676 map.insert("key".to_string(), 42i32);
677 let result = to_string(&map).unwrap();
678 assert!(result.contains("key = 42"));
680 assert!(!result.contains("\"key\""));
681 }
682}