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: style
76    };
77    value.serialize(&mut serializer)?;
78    Ok(serializer.output)
79}
80
81impl<'a> ser::Serializer for &'a 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<'a> ser::SerializeSeq for &'a 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 {
382            match self.style.indent {
383                Some(ident) => {
384                    self.output.push('\n');
385                    self.style.current_indent.reserve(ident);
386                    for _ in 0 .. ident {
387                        self.style.current_indent.push(' ');
388                    }
389                    self.output.push_str(self.style.current_indent.as_str());
390                }
391                None => {}
392            }
393        }
394        value.serialize(&mut **self)
395    }
396
397    // Close the sequence.
398    fn end(self) -> Result<()> {
399        match self.style.trailing_comma {
400            TrailingComma::ALL | TrailingComma::OBJECTS => {
401                self.output.push(',')
402            }
403            _ => {}
404        }
405        match self.style.indent {
406            Some(ident) => {
407                self.style.current_indent.truncate(self.style.current_indent.len() - ident);
408                self.output.reserve(self.style.current_indent.len() + 1);
409                self.output.push('\n');
410                self.output.push_str(self.style.current_indent.as_str());
411            }
412            None => {}
413        }
414        self.output.push(']');
415        Ok(())
416    }
417}
418
419// Same thing but for tuples.
420impl<'a> ser::SerializeTuple for &'a mut Serializer {
421    type Ok = ();
422    type Error = SerdeJSON5Error;
423
424    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
425    where
426        T: ?Sized + Serialize,
427    {
428        if !self.output.ends_with('[') {
429            match self.style.indent {
430                Some(_) => {
431                    self.output.reserve(self.style.current_indent.len() + 2);
432                    self.output += ",\n";
433                    self.output.push_str(self.style.current_indent.as_str());
434                }
435                None => {
436                    self.output.push_str(self.style.item_separator.as_str())
437                }
438            }
439        } else {
440            match self.style.indent {
441                Some(ident) => {
442                    self.output.push('\n');
443                    self.style.current_indent.reserve(ident);
444                    for _ in 0 .. ident {
445                        self.style.current_indent.push(' ');
446                    }
447                    self.output.push_str(self.style.current_indent.as_str());
448                }
449                None => {}
450            }
451        }
452        value.serialize(&mut **self)
453    }
454
455    fn end(self) -> Result<()> {
456        match self.style.trailing_comma {
457            TrailingComma::ALL | TrailingComma::OBJECTS => {
458                self.output.push(',')
459            }
460            _ => {}
461        }
462        match self.style.indent {
463            Some(ident) => {
464                self.style.current_indent.truncate(self.style.current_indent.len() - ident);
465                self.output.reserve(self.style.current_indent.len() + 1);
466                self.output.push('\n');
467                self.output.push_str(self.style.current_indent.as_str());
468            }
469            None => {}
470        }
471        self.output.push(']');
472        Ok(())
473    }
474}
475
476// Same thing but for tuple structs.
477impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
478    type Ok = ();
479    type Error = SerdeJSON5Error;
480
481    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
482    where
483        T: ?Sized + Serialize,
484    {
485        if !self.output.ends_with('[') {
486            match self.style.indent {
487                Some(_) => {
488                    self.output.reserve(self.style.current_indent.len() + 2);
489                    self.output += ",\n";
490                    self.output.push_str(self.style.current_indent.as_str());
491                }
492                None => {
493                    self.output.push_str(self.style.item_separator.as_str())
494                }
495            }
496        } else {
497            match self.style.indent {
498                Some(ident) => {
499                    self.output.push('\n');
500                    self.style.current_indent.reserve(ident);
501                    for _ in 0 .. ident {
502                        self.style.current_indent.push(' ');
503                    }
504                    self.output.push_str(self.style.current_indent.as_str());
505                }
506                None => {}
507            }
508        }
509        value.serialize(&mut **self)
510    }
511
512    fn end(self) -> Result<()> {
513        match self.style.trailing_comma {
514            TrailingComma::ALL | TrailingComma::OBJECTS => {
515                self.output.push(',')
516            }
517            _ => {}
518        }
519        match self.style.indent {
520            Some(ident) => {
521                self.style.current_indent.truncate(self.style.current_indent.len() - ident);
522                self.output.reserve(self.style.current_indent.len() + 1);
523                self.output.push('\n');
524                self.output.push_str(self.style.current_indent.as_str());
525            }
526            None => {}
527        }
528        self.output.push(']');
529        Ok(())
530    }
531}
532
533// Tuple variants are a little different. Refer back to the
534// `serialize_tuple_variant` method above:
535//
536//    self.output += "{";
537//    variant.serialize(&mut *self)?;
538//    self.output += ":[";
539//
540// So the `end` method in this impl is responsible for closing both the `]` and
541// the `}`.
542impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
543    type Ok = ();
544    type Error = SerdeJSON5Error;
545
546    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
547    where
548        T: ?Sized + Serialize,
549    {
550        if !self.output.ends_with('[') {
551            match self.style.indent {
552                Some(_) => {
553                    self.output.reserve(self.style.current_indent.len() + 2);
554                    self.output += ",\n";
555                    self.output.push_str(self.style.current_indent.as_str());
556                }
557                None => {
558                    self.output.push_str(self.style.item_separator.as_str())
559                }
560            }
561        } else {
562            match self.style.indent {
563                Some(ident) => {
564                    self.output.push('\n');
565                    self.style.current_indent.reserve(ident);
566                    for _ in 0 .. ident {
567                        self.style.current_indent.push(' ');
568                    }
569                    self.output.push_str(self.style.current_indent.as_str());
570                }
571                None => {}
572            }
573        }
574        value.serialize(&mut **self)
575    }
576
577    fn end(self) -> Result<()> {
578        match self.style.trailing_comma {
579            TrailingComma::ALL | TrailingComma::OBJECTS => {
580                self.output.push(',')
581            }
582            _ => {}
583        }
584        match self.style.indent {
585            Some(ident) => {
586                self.style.current_indent.truncate(self.style.current_indent.len() - ident);
587                self.output.reserve(self.style.current_indent.len() + 1);
588                self.output.push('\n');
589                self.output.push_str(self.style.current_indent.as_str());
590            }
591            None => {}
592        }
593        self.output.push(']');
594        match self.style.trailing_comma {
595            TrailingComma::ALL | TrailingComma::OBJECTS => {
596                self.output.push(',')
597            }
598            _ => {}
599        }
600        match self.style.indent {
601            Some(ident) => {
602                self.style.current_indent.truncate(self.style.current_indent.len() - ident);
603                self.output.reserve(self.style.current_indent.len() + 1);
604                self.output.push('\n');
605                self.output.push_str(self.style.current_indent.as_str());
606            }
607            None => {}
608        }
609        self.output.push('}');
610        Ok(())
611    }
612}
613
614// Some `Serialize` types are not able to hold a key and value in memory at the
615// same time so `SerializeMap` implementations are required to support
616// `serialize_key` and `serialize_value` individually.
617//
618// There is a third optional method on the `SerializeMap` trait. The
619// `serialize_entry` method allows serializers to optimize for the case where
620// key and value are both available simultaneously. In JSON it doesn't make a
621// difference so the default behavior for `serialize_entry` is fine.
622impl<'a> ser::SerializeMap for &'a mut Serializer {
623    type Ok = ();
624    type Error = SerdeJSON5Error;
625
626    // The Serde data model allows map keys to be any serializable type. JSON
627    // only allows string keys so the implementation below will produce invalid
628    // JSON if the key serializes as something other than a string.
629    //
630    // A real JSON serializer would need to validate that map keys are strings.
631    // This can be done by using a different Serializer to serialize the key
632    // (instead of `&mut **self`) and having that other serializer only
633    // implement `serialize_str` and return an error on any other data type.
634    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
635    where
636        T: ?Sized + Serialize,
637    {
638        if !self.output.ends_with('{') {
639            match self.style.indent {
640                Some(_) => {
641                    self.output.reserve(self.style.current_indent.len() + 2);
642                    self.output += ",\n";
643                    self.output.push_str(self.style.current_indent.as_str());
644                }
645                None => {
646                    self.output.push_str(self.style.item_separator.as_str())
647                }
648            }
649        } else {
650            match self.style.indent {
651                Some(ident) => {
652                    self.output.push('\n');
653                    self.style.current_indent.reserve(ident);
654                    for _ in 0 .. ident {
655                        self.style.current_indent.push(' ');
656                    }
657                    self.output.push_str(self.style.current_indent.as_str());
658                }
659                None => {}
660            }
661        }
662        key.serialize(&mut **self)
663    }
664
665    // It doesn't make a difference whether the colon is printed at the end of
666    // `serialize_key` or at the beginning of `serialize_value`. In this case
667    // the code is a bit simpler having it here.
668    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
669    where
670        T: ?Sized + Serialize,
671    {
672        self.output.push_str(self.style.key_separator.as_str());
673        value.serialize(&mut **self)
674    }
675
676    fn end(self) -> Result<()> {
677        match self.style.trailing_comma {
678            TrailingComma::ALL | TrailingComma::OBJECTS => {
679                self.output.push(',')
680            }
681            _ => {}
682        }
683        match self.style.indent {
684            Some(ident) => {
685                self.style.current_indent.truncate(self.style.current_indent.len() - ident);
686                self.output.reserve(self.style.current_indent.len() + 1);
687                self.output.push('\n');
688                self.output.push_str(self.style.current_indent.as_str());
689            }
690            None => {}
691        }
692        self.output.push('}');
693        Ok(())
694    }
695}
696
697// Structs are like maps in which the keys are constrained to be compile-time
698// constant strings.
699impl<'a> ser::SerializeStruct for &'a mut Serializer {
700    type Ok = ();
701    type Error = SerdeJSON5Error;
702
703    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
704    where
705        T: ?Sized + Serialize,
706    {
707        if !self.output.ends_with('{') {
708            match self.style.indent {
709                Some(_) => {
710                    self.output.reserve(self.style.current_indent.len() + 2);
711                    self.output += ",\n";
712                    self.output.push_str(self.style.current_indent.as_str());
713                }
714                None => {
715                    self.output.push_str(self.style.item_separator.as_str())
716                }
717            }
718        } else {
719            match self.style.indent {
720                Some(ident) => {
721                    self.output.push('\n');
722                    self.style.current_indent.reserve(ident);
723                    for _ in 0 .. ident {
724                        self.style.current_indent.push(' ');
725                    }
726                    self.output.push_str(self.style.current_indent.as_str());
727                }
728                None => {}
729            }
730        }
731        key.serialize(&mut **self)?;
732        self.output.push_str(self.style.key_separator.as_str());
733        value.serialize(&mut **self)
734    }
735
736    fn end(self) -> Result<()> {
737        match self.style.trailing_comma {
738            TrailingComma::ALL | TrailingComma::OBJECTS => {
739                self.output.push(',')
740            }
741            _ => {}
742        }
743        match self.style.indent {
744            Some(ident) => {
745                self.style.current_indent.truncate(self.style.current_indent.len() - ident);
746                self.output.reserve(self.style.current_indent.len() + 1);
747                self.output.push('\n');
748                self.output.push_str(self.style.current_indent.as_str());
749            }
750            None => {}
751        }
752
753        self.output.push('}');
754        Ok(())
755    }
756}
757
758
759
760// Similar to `SerializeTupleVariant`, here the `end` method is responsible for
761// closing both of the curly braces opened by `serialize_struct_variant`.
762impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
763    type Ok = ();
764    type Error = SerdeJSON5Error;
765
766    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
767    where
768        T: ?Sized + Serialize,
769    {
770        if !self.output.ends_with('{') {
771            match self.style.indent {
772                Some(_) => {
773                    self.output.reserve(self.style.current_indent.len() + 2);
774                    self.output += ",\n";
775                    self.output.push_str(self.style.current_indent.as_str());
776                }
777                None => {
778                    self.output.push_str(self.style.item_separator.as_str())
779                }
780            }
781        } else {
782            match self.style.indent {
783                Some(ident) => {
784                    self.output.push('\n');
785                    self.style.current_indent.reserve(ident);
786                    for _ in 0 .. ident {
787                        self.style.current_indent.push(' ');
788                    }
789                    self.output.push_str(self.style.current_indent.as_str());
790                }
791                None => {}
792            }
793        }
794        key.serialize(&mut **self)?;
795        self.output.push_str(self.style.key_separator.as_str());
796        value.serialize(&mut **self)
797    }
798
799    fn end(self) -> Result<()> {
800        match self.style.trailing_comma {
801            TrailingComma::ALL | TrailingComma::OBJECTS => {
802                self.output.push(',')
803            }
804            _ => {}
805        }
806        match self.style.indent {
807            Some(ident) => {
808                self.style.current_indent.truncate(self.style.current_indent.len() - ident);
809                self.output.reserve(self.style.current_indent.len() + 1);
810                self.output.push('\n');
811                self.output.push_str(self.style.current_indent.as_str());
812            }
813            None => {}
814        }
815        self.output.push('}');
816
817
818        match self.style.trailing_comma {
819            TrailingComma::ALL | TrailingComma::OBJECTS => {
820                self.output.push(',')
821            }
822            _ => {}
823        }
824        match self.style.indent {
825            Some(ident) => {
826                self.style.current_indent.truncate(self.style.current_indent.len() - ident);
827                self.output.reserve(self.style.current_indent.len() + 1);
828                self.output.push('\n');
829                self.output.push_str(self.style.current_indent.as_str());
830            }
831            None => {}
832        }
833        self.output.push('}');
834        Ok(())
835    }
836}
837
838#[cfg(test)]
839mod tests {
840    use super::*;
841    #[derive(Serialize)]
842    struct Test {
843        int: u32,
844        seq: Vec<&'static str>,
845    }
846
847    #[test]
848    fn test_struct() {
849
850        let test = Test {
851            int: 1,
852            seq: vec!["a", "b"],
853        };
854        let expected = r#"{"int": 1, "seq": ["a", "b"]}"#;
855        assert_eq!(to_string(&test).unwrap(), expected);
856    }
857    #[test]
858    fn test_struct_styled() {
859        let test = Test {
860            int: 1,
861            seq: vec!["a", "b"],
862        };
863        let expected = r#"{
864    "int": 1,
865    "seq": [
866        "a",
867        "b",
868    ],
869}"#;
870        let style = FormatConfiguration::with_indent(4, TrailingComma::ALL);
871        assert_eq!(to_string_formatted(&test, style).unwrap(), expected);
872    }
873
874
875    #[test]
876    fn test_enum() {
877        #[derive(Serialize)]
878        enum E {
879            Unit,
880            Newtype(u32),
881            Tuple(u32, u32),
882            Struct { a: u32 },
883        }
884
885        let u = E::Unit;
886        let expected = r#""Unit""#;
887        assert_eq!(to_string(&u).unwrap(), expected);
888
889        let n = E::Newtype(1);
890        let expected = r#"{"Newtype": 1}"#;
891        assert_eq!(to_string(&n).unwrap(), expected);
892
893        let t = E::Tuple(1, 2);
894        let expected = r#"{"Tuple": [1, 2]}"#;
895        assert_eq!(to_string(&t).unwrap(), expected);
896
897        let s = E::Struct { a: 1 };
898        let expected = r#"{"Struct": {"a": 1}}"#;
899        assert_eq!(to_string(&s).unwrap(), expected);
900    }
901}