json_five/
ser.rs

1use serde::{ser, Serialize};
2use crate::parser::{TrailingComma};
3use std::fmt;
4use crate::utils::{escape_double_quoted};
5
6#[derive(Debug)]
7pub enum SerdeJSON5Error {
8    Custom(String),
9}
10
11impl std::error::Error for SerdeJSON5Error {}
12impl fmt::Display for SerdeJSON5Error {
13    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14        match self {
15            SerdeJSON5Error::Custom(msg) => write!(f, "{msg}"),
16        }
17    }
18}
19
20impl ser::Error for SerdeJSON5Error {
21    fn custom<T: fmt::Display>(msg: T) -> Self {
22        SerdeJSON5Error::Custom(msg.to_string())
23    }
24}
25
26use crate::parser::FormatConfiguration;
27
28/// The JSON5 serializer implementing [ser::Serializer]
29pub struct Serializer {
30    // This string starts empty and JSON is appended as values are serialized.
31    output: String,
32    style: FormatConfiguration
33}
34
35type Result<T> = std::result::Result<T, SerdeJSON5Error>;
36
37/// Basic helper to serialize a value implementing [Serialize] to a `String`
38///
39/// # Examples
40///
41/// ```rust
42/// use serde::Serialize;
43/// use json_five::to_string;
44/// #[derive(Serialize)]
45/// struct Test {
46///     int: u32,
47///     seq: Vec<&'static str>,
48/// }
49///
50/// let test = Test {
51///     int: 1,
52///     seq: vec!["a", "b"],
53/// };
54/// let expected = r#"{"int": 1, "seq": ["a", "b"]}"#;
55/// assert_eq!(to_string(&test).unwrap(), expected);
56/// ```
57pub fn to_string<T>(value: &T) -> Result<String>
58where
59    T: Serialize,
60{
61    let mut serializer = Serializer {
62        output: String::new(),
63        style: FormatConfiguration::default()
64    };
65    value.serialize(&mut serializer)?;
66    Ok(serializer.output)
67}
68
69pub fn to_string_formatted<T>(value: &T, style: FormatConfiguration) -> Result<String>
70where
71    T: Serialize
72{
73    let mut serializer = Serializer {
74        output: String::new(),
75        style
76    };
77    value.serialize(&mut serializer)?;
78    Ok(serializer.output)
79}
80
81impl ser::Serializer for &mut Serializer {
82    // The output type produced by this `Serializer` during successful
83    // serialization. Most serializers that produce text or binary output should
84    // set `Ok = ()` and serialize into an `io::Write` or buffer contained
85    // within the `Serializer` instance, as happens here. Serializers that build
86    // in-memory data structures may be simplified by using `Ok` to propagate
87    // the data structure around.
88    type Ok = ();
89
90    // The error type when some error occurs during serialization.
91    type Error = SerdeJSON5Error;
92
93    // Associated types for keeping track of additional state while serializing
94    // compound data structures like sequences and maps. In this case no
95    // additional state is required beyond what is already stored in the
96    // Serializer struct.
97    type SerializeSeq = Self;
98    type SerializeTuple = Self;
99    type SerializeTupleStruct = Self;
100    type SerializeTupleVariant = Self;
101    type SerializeMap = Self;
102    type SerializeStruct = Self;
103    type SerializeStructVariant = Self;
104
105    // Here we go with the simple methods. The following 12 methods receive one
106    // of the primitive types of the data model and map it to JSON by appending
107    // into the output string.
108    fn serialize_bool(self, v: bool) -> Result<()> {
109        self.output += if v { "true" } else { "false" };
110        Ok(())
111    }
112
113    // JSON does not distinguish between different sizes of integers, so all
114    // signed integers will be serialized the same and all unsigned integers
115    // will be serialized the same. Other formats, especially compact binary
116    // formats, may need independent logic for the different sizes.
117    fn serialize_i8(self, v: i8) -> Result<()> {
118        self.serialize_i64(i64::from(v))
119    }
120
121    fn serialize_i16(self, v: i16) -> Result<()> {
122        self.serialize_i64(i64::from(v))
123    }
124
125    fn serialize_i32(self, v: i32) -> Result<()> {
126        self.serialize_i64(i64::from(v))
127    }
128
129    // Not particularly efficient but this is example code anyway. A more
130    // performant approach would be to use the `itoa` crate.
131    fn serialize_i64(self, v: i64) -> Result<()> {
132        self.output += &v.to_string();
133        Ok(())
134    }
135
136    fn serialize_u8(self, v: u8) -> Result<()> {
137        self.serialize_u64(u64::from(v))
138    }
139
140    fn serialize_u16(self, v: u16) -> Result<()> {
141        self.serialize_u64(u64::from(v))
142    }
143
144    fn serialize_u32(self, v: u32) -> Result<()> {
145        self.serialize_u64(u64::from(v))
146    }
147
148    fn serialize_u64(self, v: u64) -> Result<()> {
149        self.output += &v.to_string();
150        Ok(())
151    }
152
153    fn serialize_f32(self, v: f32) -> Result<()> {
154        self.serialize_f64(f64::from(v))
155    }
156
157    fn serialize_f64(self, v: f64) -> Result<()> {
158        self.output += &v.to_string();
159        Ok(())
160    }
161
162    // Serialize a char as a single-character string. Other formats may
163    // represent this differently.
164    fn serialize_char(self, v: char) -> Result<()> {
165        self.serialize_str(&v.to_string())
166    }
167
168    // This only works for strings that don't require escape sequences but you
169    // get the idea. For example it would emit invalid JSON if the input string
170    // contains a '"' character.
171    fn serialize_str(self, v: &str) -> Result<()> {
172        self.output += "\"";
173        self.output += escape_double_quoted(v).as_str();
174        self.output += "\"";
175        Ok(())
176    }
177
178    // Serialize a byte array as an array of bytes. Could also use a base64
179    // string here. Binary formats will typically represent byte arrays more
180    // compactly.
181    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
182        use serde::ser::SerializeSeq;
183        let mut seq = self.serialize_seq(Some(v.len()))?;
184        for byte in v {
185            seq.serialize_element(byte)?;
186        }
187        seq.end()
188    }
189
190    // An absent optional is represented as the JSON `null`.
191    fn serialize_none(self) -> Result<()> {
192        self.serialize_unit()
193    }
194
195    // A present optional is represented as just the contained value. Note that
196    // this is a lossy representation. For example the values `Some(())` and
197    // `None` both serialize as just `null`. Unfortunately this is typically
198    // what people expect when working with JSON. Other formats are encouraged
199    // to behave more intelligently if possible.
200    fn serialize_some<T>(self, value: &T) -> Result<()>
201    where
202        T: ?Sized + Serialize,
203    {
204        value.serialize(self)
205    }
206
207    // In Serde, unit means an anonymous value containing no data. Map this to
208    // JSON as `null`.
209    fn serialize_unit(self) -> Result<()> {
210        self.output += "null";
211        Ok(())
212    }
213
214    // Unit struct means a named value containing no data. Again, since there is
215    // no data, map this to JSON as `null`. There is no need to serialize the
216    // name in most formats.
217    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
218        self.serialize_unit()
219    }
220
221    // When serializing a unit variant (or any other kind of variant), formats
222    // can choose whether to keep track of it by index or by name. Binary
223    // formats typically use the index of the variant and human-readable formats
224    // typically use the name.
225    fn serialize_unit_variant(
226        self,
227        _name: &'static str,
228        _variant_index: u32,
229        variant: &'static str,
230    ) -> Result<()> {
231        self.serialize_str(variant)
232    }
233
234    // As is done here, serializers are encouraged to treat newtype structs as
235    // insignificant wrappers around the data they contain.
236    fn serialize_newtype_struct<T>(
237        self,
238        _name: &'static str,
239        value: &T,
240    ) -> Result<()>
241    where
242        T: ?Sized + Serialize,
243    {
244        value.serialize(self)
245    }
246
247    // Note that newtype variant (and all of the other variant serialization
248    // methods) refer exclusively to the "externally tagged" enum
249    // representation.
250    //
251    // Serialize this to JSON in externally tagged form as `{ NAME: VALUE }`.
252    fn serialize_newtype_variant<T>(
253        self,
254        _name: &'static str,
255        _variant_index: u32,
256        variant: &'static str,
257        value: &T,
258    ) -> Result<()>
259    where
260        T: ?Sized + Serialize,
261    {
262        self.output.push('{');
263        variant.serialize(&mut *self)?;
264        self.output.push_str(self.style.key_separator.as_str());
265        value.serialize(&mut *self)?;
266        self.output.push('}');
267        Ok(())
268    }
269
270    // Now we get to the serialization of compound types.
271    //
272    // The start of the sequence, each value, and the end are three separate
273    // method calls. This one is responsible only for serializing the start,
274    // which in JSON is `[`.
275    //
276    // The length of the sequence may or may not be known ahead of time. This
277    // doesn't make a difference in JSON because the length is not represented
278    // explicitly in the serialized form. Some serializers may only be able to
279    // support sequences for which the length is known up front.
280    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
281        self.output += "[";
282        Ok(self)
283    }
284
285    // Tuples look just like sequences in JSON. Some formats may be able to
286    // represent tuples more efficiently by omitting the length, since tuple
287    // means that the corresponding `Deserialize implementation will know the
288    // length without needing to look at the serialized data.
289    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
290        self.serialize_seq(Some(len))
291    }
292
293    // Tuple structs look just like sequences in JSON.
294    fn serialize_tuple_struct(
295        self,
296        _name: &'static str,
297        len: usize,
298    ) -> Result<Self::SerializeTupleStruct> {
299        self.serialize_seq(Some(len))
300    }
301
302    // Tuple variants are represented in JSON as `{ NAME: [DATA...] }`. Again
303    // this method is only responsible for the externally tagged representation.
304    fn serialize_tuple_variant(
305        self,
306        _name: &'static str,
307        _variant_index: u32,
308        variant: &'static str,
309        _len: usize,
310    ) -> Result<Self::SerializeTupleVariant> {
311        self.output.push('{');
312        variant.serialize(&mut *self)?;
313        self.output.push_str(format!("{}[", self.style.key_separator).as_str());
314        Ok(self)
315    }
316
317    // Maps are represented in JSON as `{ K: V, K: V, ... }`.
318    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
319        self.output.push('{');
320        Ok(self)
321    }
322
323    // Structs look just like maps in JSON. In particular, JSON requires that we
324    // serialize the field names of the struct. Other formats may be able to
325    // omit the field names when serializing structs because the corresponding
326    // Deserialize implementation is required to know what the keys are without
327    // looking at the serialized data.
328    fn serialize_struct(
329        self,
330        _name: &'static str,
331        len: usize,
332    ) -> Result<Self::SerializeStruct> {
333        self.serialize_map(Some(len))
334    }
335
336    // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }`.
337    // This is the externally tagged representation.
338    fn serialize_struct_variant(
339        self,
340        _name: &'static str,
341        _variant_index: u32,
342        variant: &'static str,
343        _len: usize,
344    ) -> Result<Self::SerializeStructVariant> {
345        self.output.push('{');
346        variant.serialize(&mut *self)?;
347        self.output.push_str(format!("{}{{", self.style.key_separator).as_str());
348        Ok(self)
349    }
350}
351
352// The following 7 impls deal with the serialization of compound types like
353// sequences and maps. Serialization of such types is begun by a Serializer
354// method and followed by zero or more calls to serialize individual elements of
355// the compound type and one call to end the compound type.
356//
357// This impl is SerializeSeq so these methods are called after `serialize_seq`
358// is called on the Serializer.
359impl ser::SerializeSeq for &mut Serializer {
360    // Must match the `Ok` type of the serializer.
361    type Ok = ();
362    // Must match the `Error` type of the serializer.
363    type Error = SerdeJSON5Error;
364
365    // Serialize a single element of the sequence.
366    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
367    where
368        T: ?Sized + Serialize,
369    {
370        if !self.output.ends_with('[') {
371            match self.style.indent {
372                Some(_) => {
373                    self.output.reserve(self.style.current_indent.len() + 2);
374                    self.output += ",\n";
375                    self.output.push_str(self.style.current_indent.as_str());
376                }
377                None => {
378                    self.output.push_str(self.style.item_separator.as_str())
379                }
380            }
381        } else if let Some(ident) = self.style.indent {
382            self.output.push('\n');
383            self.style.current_indent.reserve(ident);
384            for _ in 0 .. ident {
385                self.style.current_indent.push(' ');
386            }
387            self.output.push_str(self.style.current_indent.as_str());
388        }
389        value.serialize(&mut **self)
390    }
391
392    // Close the sequence.
393    fn end(self) -> Result<()> {
394        match self.style.trailing_comma {
395            TrailingComma::ALL | TrailingComma::OBJECTS => {
396                self.output.push(',')
397            }
398            _ => {}
399        }
400        if let Some(ident) = self.style.indent {
401            self.style.current_indent.truncate(self.style.current_indent.len() - ident);
402            self.output.reserve(self.style.current_indent.len() + 1);
403            self.output.push('\n');
404            self.output.push_str(self.style.current_indent.as_str());
405        }
406        self.output.push(']');
407        Ok(())
408    }
409}
410
411// Same thing but for tuples.
412impl ser::SerializeTuple for &mut Serializer {
413    type Ok = ();
414    type Error = SerdeJSON5Error;
415
416    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
417    where
418        T: ?Sized + Serialize,
419    {
420        if !self.output.ends_with('[') {
421            match self.style.indent {
422                Some(_) => {
423                    self.output.reserve(self.style.current_indent.len() + 2);
424                    self.output += ",\n";
425                    self.output.push_str(self.style.current_indent.as_str());
426                }
427                None => {
428                    self.output.push_str(self.style.item_separator.as_str())
429                }
430            }
431        } else if let Some(ident) = self.style.indent {
432            self.output.push('\n');
433            self.style.current_indent.reserve(ident);
434            for _ in 0 .. ident {
435                self.style.current_indent.push(' ');
436            }
437            self.output.push_str(self.style.current_indent.as_str());
438        }
439        value.serialize(&mut **self)
440    }
441
442    fn end(self) -> Result<()> {
443        match self.style.trailing_comma {
444            TrailingComma::ALL | TrailingComma::OBJECTS => {
445                self.output.push(',')
446            }
447            _ => {}
448        }
449        if let Some(ident) = self.style.indent {
450            self.style.current_indent.truncate(self.style.current_indent.len() - ident);
451            self.output.reserve(self.style.current_indent.len() + 1);
452            self.output.push('\n');
453            self.output.push_str(self.style.current_indent.as_str());
454        }
455        self.output.push(']');
456        Ok(())
457    }
458}
459
460// Same thing but for tuple structs.
461impl ser::SerializeTupleStruct for &mut Serializer {
462    type Ok = ();
463    type Error = SerdeJSON5Error;
464
465    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
466    where
467        T: ?Sized + Serialize,
468    {
469        if !self.output.ends_with('[') {
470            match self.style.indent {
471                Some(_) => {
472                    self.output.reserve(self.style.current_indent.len() + 2);
473                    self.output += ",\n";
474                    self.output.push_str(self.style.current_indent.as_str());
475                }
476                None => {
477                    self.output.push_str(self.style.item_separator.as_str())
478                }
479            }
480        } else if let Some(ident) = self.style.indent {
481            self.output.push('\n');
482            self.style.current_indent.reserve(ident);
483            for _ in 0 .. ident {
484                self.style.current_indent.push(' ');
485            }
486            self.output.push_str(self.style.current_indent.as_str());
487        }
488        value.serialize(&mut **self)
489    }
490
491    fn end(self) -> Result<()> {
492        match self.style.trailing_comma {
493            TrailingComma::ALL | TrailingComma::OBJECTS => {
494                self.output.push(',')
495            }
496            _ => {}
497        }
498        if let Some(ident) = self.style.indent {
499            self.style.current_indent.truncate(self.style.current_indent.len() - ident);
500            self.output.reserve(self.style.current_indent.len() + 1);
501            self.output.push('\n');
502            self.output.push_str(self.style.current_indent.as_str());
503        }
504        self.output.push(']');
505        Ok(())
506    }
507}
508
509// Tuple variants are a little different. Refer back to the
510// `serialize_tuple_variant` method above:
511//
512//    self.output += "{";
513//    variant.serialize(&mut *self)?;
514//    self.output += ":[";
515//
516// So the `end` method in this impl is responsible for closing both the `]` and
517// the `}`.
518impl ser::SerializeTupleVariant for &mut Serializer {
519    type Ok = ();
520    type Error = SerdeJSON5Error;
521
522    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
523    where
524        T: ?Sized + Serialize,
525    {
526        if !self.output.ends_with('[') {
527            match self.style.indent {
528                Some(_) => {
529                    self.output.reserve(self.style.current_indent.len() + 2);
530                    self.output += ",\n";
531                    self.output.push_str(self.style.current_indent.as_str());
532                }
533                None => {
534                    self.output.push_str(self.style.item_separator.as_str())
535                }
536            }
537        } else if let Some(ident) = self.style.indent {
538            self.output.push('\n');
539            self.style.current_indent.reserve(ident);
540            for _ in 0 .. ident {
541                self.style.current_indent.push(' ');
542            }
543            self.output.push_str(self.style.current_indent.as_str());
544        }
545        value.serialize(&mut **self)
546    }
547
548    fn end(self) -> Result<()> {
549        match self.style.trailing_comma {
550            TrailingComma::ALL | TrailingComma::OBJECTS => {
551                self.output.push(',')
552            }
553            _ => {}
554        }
555        if let Some(ident) = self.style.indent {
556            self.style.current_indent.truncate(self.style.current_indent.len() - ident);
557            self.output.reserve(self.style.current_indent.len() + 1);
558            self.output.push('\n');
559            self.output.push_str(self.style.current_indent.as_str());
560        }
561        self.output.push(']');
562        match self.style.trailing_comma {
563            TrailingComma::ALL | TrailingComma::OBJECTS => {
564                self.output.push(',')
565            }
566            _ => {}
567        }
568        if let Some(ident) = self.style.indent {
569            self.style.current_indent.truncate(self.style.current_indent.len() - ident);
570            self.output.reserve(self.style.current_indent.len() + 1);
571            self.output.push('\n');
572            self.output.push_str(self.style.current_indent.as_str());
573        }
574        self.output.push('}');
575        Ok(())
576    }
577}
578
579// Some `Serialize` types are not able to hold a key and value in memory at the
580// same time so `SerializeMap` implementations are required to support
581// `serialize_key` and `serialize_value` individually.
582//
583// There is a third optional method on the `SerializeMap` trait. The
584// `serialize_entry` method allows serializers to optimize for the case where
585// key and value are both available simultaneously. In JSON it doesn't make a
586// difference so the default behavior for `serialize_entry` is fine.
587impl ser::SerializeMap for &mut Serializer {
588    type Ok = ();
589    type Error = SerdeJSON5Error;
590
591    // The Serde data model allows map keys to be any serializable type. JSON
592    // only allows string keys so the implementation below will produce invalid
593    // JSON if the key serializes as something other than a string.
594    //
595    // A real JSON serializer would need to validate that map keys are strings.
596    // This can be done by using a different Serializer to serialize the key
597    // (instead of `&mut **self`) and having that other serializer only
598    // implement `serialize_str` and return an error on any other data type.
599    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
600    where
601        T: ?Sized + Serialize,
602    {
603        if !self.output.ends_with('{') {
604            match self.style.indent {
605                Some(_) => {
606                    self.output.reserve(self.style.current_indent.len() + 2);
607                    self.output += ",\n";
608                    self.output.push_str(self.style.current_indent.as_str());
609                }
610                None => {
611                    self.output.push_str(self.style.item_separator.as_str())
612                }
613            }
614        } else if let Some(ident) = self.style.indent {
615            self.output.push('\n');
616            self.style.current_indent.reserve(ident);
617            for _ in 0 .. ident {
618                self.style.current_indent.push(' ');
619            }
620            self.output.push_str(self.style.current_indent.as_str());
621        }
622        key.serialize(&mut **self)
623    }
624
625    // It doesn't make a difference whether the colon is printed at the end of
626    // `serialize_key` or at the beginning of `serialize_value`. In this case
627    // the code is a bit simpler having it here.
628    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
629    where
630        T: ?Sized + Serialize,
631    {
632        self.output.push_str(self.style.key_separator.as_str());
633        value.serialize(&mut **self)
634    }
635
636    fn end(self) -> Result<()> {
637        match self.style.trailing_comma {
638            TrailingComma::ALL | TrailingComma::OBJECTS => {
639                self.output.push(',')
640            }
641            _ => {}
642        }
643        if let Some(ident) = self.style.indent {
644            self.style.current_indent.truncate(self.style.current_indent.len() - ident);
645            self.output.reserve(self.style.current_indent.len() + 1);
646            self.output.push('\n');
647            self.output.push_str(self.style.current_indent.as_str());
648        }
649        self.output.push('}');
650        Ok(())
651    }
652}
653
654// Structs are like maps in which the keys are constrained to be compile-time
655// constant strings.
656impl ser::SerializeStruct for &mut Serializer {
657    type Ok = ();
658    type Error = SerdeJSON5Error;
659
660    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
661    where
662        T: ?Sized + Serialize,
663    {
664        if !self.output.ends_with('{') {
665            match self.style.indent {
666                Some(_) => {
667                    self.output.reserve(self.style.current_indent.len() + 2);
668                    self.output += ",\n";
669                    self.output.push_str(self.style.current_indent.as_str());
670                }
671                None => {
672                    self.output.push_str(self.style.item_separator.as_str())
673                }
674            }
675        } else if let Some(ident) = self.style.indent {
676            self.output.push('\n');
677            self.style.current_indent.reserve(ident);
678            for _ in 0 .. ident {
679                self.style.current_indent.push(' ');
680            }
681            self.output.push_str(self.style.current_indent.as_str());
682        }
683        key.serialize(&mut **self)?;
684        self.output.push_str(self.style.key_separator.as_str());
685        value.serialize(&mut **self)
686    }
687
688    fn end(self) -> Result<()> {
689        match self.style.trailing_comma {
690            TrailingComma::ALL | TrailingComma::OBJECTS => {
691                self.output.push(',')
692            }
693            _ => {}
694        }
695        if let Some(ident) = self.style.indent {
696            self.style.current_indent.truncate(self.style.current_indent.len() - ident);
697            self.output.reserve(self.style.current_indent.len() + 1);
698            self.output.push('\n');
699            self.output.push_str(self.style.current_indent.as_str());
700        }
701
702        self.output.push('}');
703        Ok(())
704    }
705}
706
707
708
709// Similar to `SerializeTupleVariant`, here the `end` method is responsible for
710// closing both of the curly braces opened by `serialize_struct_variant`.
711impl ser::SerializeStructVariant for &mut Serializer {
712    type Ok = ();
713    type Error = SerdeJSON5Error;
714
715    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
716    where
717        T: ?Sized + Serialize,
718    {
719        if !self.output.ends_with('{') {
720            match self.style.indent {
721                Some(_) => {
722                    self.output.reserve(self.style.current_indent.len() + 2);
723                    self.output += ",\n";
724                    self.output.push_str(self.style.current_indent.as_str());
725                }
726                None => {
727                    self.output.push_str(self.style.item_separator.as_str())
728                }
729            }
730        } else if let Some(ident) = self.style.indent {
731            self.output.push('\n');
732            self.style.current_indent.reserve(ident);
733            for _ in 0 .. ident {
734                self.style.current_indent.push(' ');
735            }
736            self.output.push_str(self.style.current_indent.as_str());
737        }
738        key.serialize(&mut **self)?;
739        self.output.push_str(self.style.key_separator.as_str());
740        value.serialize(&mut **self)
741    }
742
743    fn end(self) -> Result<()> {
744        match self.style.trailing_comma {
745            TrailingComma::ALL | TrailingComma::OBJECTS => {
746                self.output.push(',')
747            }
748            _ => {}
749        }
750        if let Some(ident) = self.style.indent {
751            self.style.current_indent.truncate(self.style.current_indent.len() - ident);
752            self.output.reserve(self.style.current_indent.len() + 1);
753            self.output.push('\n');
754            self.output.push_str(self.style.current_indent.as_str());
755        }
756        self.output.push('}');
757
758
759        match self.style.trailing_comma {
760            TrailingComma::ALL | TrailingComma::OBJECTS => {
761                self.output.push(',')
762            }
763            _ => {}
764        }
765        if let Some(ident) = self.style.indent {
766            self.style.current_indent.truncate(self.style.current_indent.len() - ident);
767            self.output.reserve(self.style.current_indent.len() + 1);
768            self.output.push('\n');
769            self.output.push_str(self.style.current_indent.as_str());
770        }
771        self.output.push('}');
772        Ok(())
773    }
774}
775
776#[cfg(test)]
777mod tests {
778    use super::*;
779    #[derive(Serialize)]
780    struct Test {
781        int: u32,
782        seq: Vec<&'static str>,
783    }
784
785    #[test]
786    fn test_struct() {
787
788        let test = Test {
789            int: 1,
790            seq: vec!["a", "b"],
791        };
792        let expected = r#"{"int": 1, "seq": ["a", "b"]}"#;
793        assert_eq!(to_string(&test).unwrap(), expected);
794    }
795    #[test]
796    fn test_struct_styled() {
797        let test = Test {
798            int: 1,
799            seq: vec!["a", "b"],
800        };
801        let expected = r#"{
802    "int": 1,
803    "seq": [
804        "a",
805        "b",
806    ],
807}"#;
808        let style = FormatConfiguration::with_indent(4, TrailingComma::ALL);
809        assert_eq!(to_string_formatted(&test, style).unwrap(), expected);
810    }
811
812
813    #[test]
814    fn test_enum() {
815        #[derive(Serialize)]
816        enum E {
817            Unit,
818            Newtype(u32),
819            Tuple(u32, u32),
820            Struct { a: u32 },
821        }
822
823        let u = E::Unit;
824        let expected = r#""Unit""#;
825        assert_eq!(to_string(&u).unwrap(), expected);
826
827        let n = E::Newtype(1);
828        let expected = r#"{"Newtype": 1}"#;
829        assert_eq!(to_string(&n).unwrap(), expected);
830
831        let t = E::Tuple(1, 2);
832        let expected = r#"{"Tuple": [1, 2]}"#;
833        assert_eq!(to_string(&t).unwrap(), expected);
834
835        let s = E::Struct { a: 1 };
836        let expected = r#"{"Struct": {"a": 1}}"#;
837        assert_eq!(to_string(&s).unwrap(), expected);
838    }
839}