serde_hjson/
ser.rs

1//! Hjson Serialization
2//!
3//! This module provides for Hjson serialization with the type `Serializer`.
4
5use std::fmt::{Display, LowerExp};
6use std::io;
7use std::num::FpCategory;
8
9use super::error::{Error, ErrorCode, Result};
10use serde::ser;
11
12use super::util::ParseNumber;
13
14use regex::Regex;
15
16/// A structure for serializing Rust values into Hjson.
17pub struct Serializer<W, F> {
18    writer: W,
19    formatter: F,
20}
21
22impl<'a, W> Serializer<W, HjsonFormatter<'a>>
23where
24    W: io::Write,
25{
26    /// Creates a new Hjson serializer.
27    #[inline]
28    pub fn new(writer: W) -> Self {
29        Serializer::with_formatter(writer, HjsonFormatter::new())
30    }
31}
32
33impl<W, F> Serializer<W, F>
34where
35    W: io::Write,
36    F: Formatter,
37{
38    /// Creates a new Hjson visitor whose output will be written to the writer
39    /// specified.
40    #[inline]
41    pub fn with_formatter(writer: W, formatter: F) -> Self {
42        Self { writer, formatter }
43    }
44
45    /// Unwrap the `Writer` from the `Serializer`.
46    #[inline]
47    pub fn into_inner(self) -> W {
48        self.writer
49    }
50}
51
52#[doc(hidden)]
53#[derive(Eq, PartialEq)]
54pub enum State {
55    Empty,
56    First,
57    Rest,
58}
59
60#[doc(hidden)]
61pub struct Compound<'a, W, F> {
62    ser: &'a mut Serializer<W, F>,
63    state: State,
64}
65
66impl<'a, W, F> ser::Serializer for &'a mut Serializer<W, F>
67where
68    W: io::Write,
69    F: Formatter,
70{
71    type Ok = ();
72    type Error = Error;
73
74    type SerializeSeq = Compound<'a, W, F>;
75    type SerializeTuple = Compound<'a, W, F>;
76    type SerializeTupleStruct = Compound<'a, W, F>;
77    type SerializeTupleVariant = Compound<'a, W, F>;
78    type SerializeMap = Compound<'a, W, F>;
79    type SerializeStruct = Compound<'a, W, F>;
80    type SerializeStructVariant = Compound<'a, W, F>;
81
82    #[inline]
83    fn serialize_bool(self, value: bool) -> Result<()> {
84        self.formatter.start_value(&mut self.writer)?;
85        if value {
86            self.writer.write_all(b"true").map_err(From::from)
87        } else {
88            self.writer.write_all(b"false").map_err(From::from)
89        }
90    }
91
92    #[inline]
93    fn serialize_i8(self, value: i8) -> Result<()> {
94        self.formatter.start_value(&mut self.writer)?;
95        write!(&mut self.writer, "{}", value).map_err(From::from)
96    }
97
98    #[inline]
99    fn serialize_i16(self, value: i16) -> Result<()> {
100        self.formatter.start_value(&mut self.writer)?;
101        write!(&mut self.writer, "{}", value).map_err(From::from)
102    }
103
104    #[inline]
105    fn serialize_i32(self, value: i32) -> Result<()> {
106        self.formatter.start_value(&mut self.writer)?;
107        write!(&mut self.writer, "{}", value).map_err(From::from)
108    }
109
110    #[inline]
111    fn serialize_i64(self, value: i64) -> Result<()> {
112        self.formatter.start_value(&mut self.writer)?;
113        write!(&mut self.writer, "{}", value).map_err(From::from)
114    }
115
116    #[inline]
117    fn serialize_u8(self, value: u8) -> Result<()> {
118        self.formatter.start_value(&mut self.writer)?;
119        write!(&mut self.writer, "{}", value).map_err(From::from)
120    }
121
122    #[inline]
123    fn serialize_u16(self, value: u16) -> Result<()> {
124        self.formatter.start_value(&mut self.writer)?;
125        write!(&mut self.writer, "{}", value).map_err(From::from)
126    }
127
128    #[inline]
129    fn serialize_u32(self, value: u32) -> Result<()> {
130        self.formatter.start_value(&mut self.writer)?;
131        write!(&mut self.writer, "{}", value).map_err(From::from)
132    }
133
134    #[inline]
135    fn serialize_u64(self, value: u64) -> Result<()> {
136        self.formatter.start_value(&mut self.writer)?;
137        write!(&mut self.writer, "{}", value).map_err(From::from)
138    }
139
140    #[inline]
141    fn serialize_f32(self, value: f32) -> Result<()> {
142        self.formatter.start_value(&mut self.writer)?;
143        fmt_f32_or_null(&mut self.writer, if value == -0f32 { 0f32 } else { value })
144            .map_err(From::from)
145    }
146
147    #[inline]
148    fn serialize_f64(self, value: f64) -> Result<()> {
149        self.formatter.start_value(&mut self.writer)?;
150        fmt_f64_or_null(&mut self.writer, if value == -0f64 { 0f64 } else { value })
151            .map_err(From::from)
152    }
153
154    #[inline]
155    fn serialize_char(self, value: char) -> Result<()> {
156        self.formatter.start_value(&mut self.writer)?;
157        escape_char(&mut self.writer, value).map_err(From::from)
158    }
159
160    #[inline]
161    fn serialize_str(self, value: &str) -> Result<()> {
162        quote_str(&mut self.writer, &mut self.formatter, value).map_err(From::from)
163    }
164
165    #[inline]
166    fn serialize_bytes(self, value: &[u8]) -> Result<()> {
167        let mut seq = self.serialize_seq(Some(value.len()))?;
168        for byte in value {
169            ser::SerializeSeq::serialize_element(&mut seq, byte)?;
170        }
171        ser::SerializeSeq::end(seq)
172    }
173
174    #[inline]
175    fn serialize_unit(self) -> Result<()> {
176        self.formatter.start_value(&mut self.writer)?;
177        self.writer.write_all(b"null").map_err(From::from)
178    }
179
180    #[inline]
181    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
182        self.serialize_unit()
183    }
184
185    #[inline]
186    fn serialize_unit_variant(
187        self,
188        _name: &'static str,
189        _variant_index: u32,
190        variant: &'static str,
191    ) -> Result<()> {
192        self.serialize_str(variant)
193    }
194
195    /// Serialize newtypes without an object wrapper.
196    #[inline]
197    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
198    where
199        T: ?Sized + ser::Serialize,
200    {
201        value.serialize(self)
202    }
203
204    #[inline]
205    fn serialize_newtype_variant<T>(
206        self,
207        _name: &'static str,
208        _variant_index: u32,
209        variant: &'static str,
210        value: &T,
211    ) -> Result<()>
212    where
213        T: ?Sized + ser::Serialize,
214    {
215        self.formatter.open(&mut self.writer, b'{')?;
216        self.formatter.comma(&mut self.writer, true)?;
217        escape_key(&mut self.writer, variant)?;
218        self.formatter.colon(&mut self.writer)?;
219        value.serialize(&mut *self)?;
220        self.formatter.close(&mut self.writer, b'}')
221    }
222
223    #[inline]
224    fn serialize_none(self) -> Result<()> {
225        self.serialize_unit()
226    }
227
228    #[inline]
229    fn serialize_some<V>(self, value: &V) -> Result<()>
230    where
231        V: ?Sized + ser::Serialize,
232    {
233        value.serialize(self)
234    }
235
236    #[inline]
237    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
238        let state = if len == Some(0) {
239            self.formatter.start_value(&mut self.writer)?;
240            self.writer.write_all(b"[]")?;
241            State::Empty
242        } else {
243            self.formatter.open(&mut self.writer, b'[')?;
244            State::First
245        };
246        Ok(Compound { ser: self, state })
247    }
248
249    #[inline]
250    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
251        self.serialize_seq(Some(len))
252    }
253
254    #[inline]
255    fn serialize_tuple_struct(
256        self,
257        _name: &'static str,
258        len: usize,
259    ) -> Result<Self::SerializeTupleStruct> {
260        self.serialize_seq(Some(len))
261    }
262
263    #[inline]
264    fn serialize_tuple_variant(
265        self,
266        _name: &'static str,
267        _variant_index: u32,
268        variant: &'static str,
269        len: usize,
270    ) -> Result<Self::SerializeTupleVariant> {
271        self.formatter.open(&mut self.writer, b'{')?;
272        self.formatter.comma(&mut self.writer, true)?;
273        escape_key(&mut self.writer, variant)?;
274        self.formatter.colon(&mut self.writer)?;
275        self.serialize_seq(Some(len))
276    }
277
278    #[inline]
279    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
280        let state = if len == Some(0) {
281            self.formatter.start_value(&mut self.writer)?;
282            self.writer.write_all(b"{}")?;
283            State::Empty
284        } else {
285            self.formatter.open(&mut self.writer, b'{')?;
286            State::First
287        };
288        Ok(Compound { ser: self, state })
289    }
290
291    #[inline]
292    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
293        self.serialize_map(Some(len))
294    }
295
296    #[inline]
297    fn serialize_struct_variant(
298        self,
299        _name: &'static str,
300        _variant_index: u32,
301        variant: &'static str,
302        len: usize,
303    ) -> Result<Self::SerializeStructVariant> {
304        self.formatter.open(&mut self.writer, b'{')?;
305        self.formatter.comma(&mut self.writer, true)?;
306        escape_key(&mut self.writer, variant)?;
307        self.formatter.colon(&mut self.writer)?;
308        self.serialize_map(Some(len))
309    }
310}
311
312impl<'a, W, F> ser::SerializeSeq for Compound<'a, W, F>
313where
314    W: io::Write,
315    F: Formatter,
316{
317    type Ok = ();
318    type Error = Error;
319
320    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
321    where
322        T: serde::Serialize + ?Sized,
323    {
324        self.ser
325            .formatter
326            .comma(&mut self.ser.writer, self.state == State::First)?;
327        self.state = State::Rest;
328        value.serialize(&mut *self.ser)
329    }
330
331    fn end(self) -> Result<Self::Ok> {
332        match self.state {
333            State::Empty => Ok(()),
334            _ => self.ser.formatter.close(&mut self.ser.writer, b']'),
335        }
336    }
337}
338
339impl<'a, W, F> ser::SerializeTuple for Compound<'a, W, F>
340where
341    W: io::Write,
342    F: Formatter,
343{
344    type Ok = ();
345    type Error = Error;
346
347    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
348    where
349        T: serde::Serialize + ?Sized,
350    {
351        ser::SerializeSeq::serialize_element(self, value)
352    }
353
354    fn end(self) -> Result<Self::Ok> {
355        ser::SerializeSeq::end(self)
356    }
357}
358
359impl<'a, W, F> ser::SerializeTupleStruct for Compound<'a, W, F>
360where
361    W: io::Write,
362    F: Formatter,
363{
364    type Ok = ();
365    type Error = Error;
366
367    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
368    where
369        T: serde::Serialize + ?Sized,
370    {
371        ser::SerializeSeq::serialize_element(self, value)
372    }
373
374    fn end(self) -> Result<Self::Ok> {
375        ser::SerializeSeq::end(self)
376    }
377}
378
379impl<'a, W, F> ser::SerializeTupleVariant for Compound<'a, W, F>
380where
381    W: io::Write,
382    F: Formatter,
383{
384    type Ok = ();
385    type Error = Error;
386
387    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
388    where
389        T: serde::Serialize + ?Sized,
390    {
391        ser::SerializeSeq::serialize_element(self, value)
392    }
393
394    fn end(self) -> Result<Self::Ok> {
395        match self.state {
396            State::Empty => {}
397            _ => self.ser.formatter.close(&mut self.ser.writer, b']')?,
398        }
399        self.ser.formatter.close(&mut self.ser.writer, b'}')
400    }
401}
402
403impl<'a, W, F> ser::SerializeMap for Compound<'a, W, F>
404where
405    W: io::Write,
406    F: Formatter,
407{
408    type Ok = ();
409    type Error = Error;
410
411    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
412    where
413        T: serde::Serialize + ?Sized,
414    {
415        self.ser
416            .formatter
417            .comma(&mut self.ser.writer, self.state == State::First)?;
418        self.state = State::Rest;
419
420        key.serialize(MapKeySerializer { ser: self.ser })?;
421
422        self.ser.formatter.colon(&mut self.ser.writer)
423    }
424
425    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
426    where
427        T: serde::Serialize + ?Sized,
428    {
429        value.serialize(&mut *self.ser)
430    }
431
432    fn end(self) -> Result<Self::Ok> {
433        match self.state {
434            State::Empty => Ok(()),
435            _ => self.ser.formatter.close(&mut self.ser.writer, b'}'),
436        }
437    }
438}
439
440impl<'a, W, F> ser::SerializeStruct for Compound<'a, W, F>
441where
442    W: io::Write,
443    F: Formatter,
444{
445    type Ok = ();
446    type Error = Error;
447
448    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
449    where
450        T: serde::Serialize + ?Sized,
451    {
452        ser::SerializeMap::serialize_entry(self, key, value)
453    }
454
455    fn end(self) -> Result<Self::Ok> {
456        ser::SerializeMap::end(self)
457    }
458}
459
460impl<'a, W, F> ser::SerializeStructVariant for Compound<'a, W, F>
461where
462    W: io::Write,
463    F: Formatter,
464{
465    type Ok = ();
466    type Error = Error;
467
468    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
469    where
470        T: serde::Serialize + ?Sized,
471    {
472        ser::SerializeStruct::serialize_field(self, key, value)
473    }
474
475    fn end(self) -> Result<Self::Ok> {
476        match self.state {
477            State::Empty => {}
478            _ => self.ser.formatter.close(&mut self.ser.writer, b'}')?,
479        }
480        self.ser.formatter.close(&mut self.ser.writer, b'}')
481    }
482}
483
484struct MapKeySerializer<'a, W: 'a, F: 'a> {
485    ser: &'a mut Serializer<W, F>,
486}
487
488impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F>
489where
490    W: io::Write,
491    F: Formatter,
492{
493    type Ok = ();
494    type Error = Error;
495
496    #[inline]
497    fn serialize_str(self, value: &str) -> Result<()> {
498        escape_key(&mut self.ser.writer, value).map_err(From::from)
499    }
500
501    type SerializeSeq = ser::Impossible<(), Error>;
502    type SerializeTuple = ser::Impossible<(), Error>;
503    type SerializeTupleStruct = ser::Impossible<(), Error>;
504    type SerializeTupleVariant = ser::Impossible<(), Error>;
505    type SerializeMap = ser::Impossible<(), Error>;
506    type SerializeStruct = ser::Impossible<(), Error>;
507    type SerializeStructVariant = ser::Impossible<(), Error>;
508
509    fn serialize_bool(self, _value: bool) -> Result<()> {
510        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
511    }
512
513    fn serialize_i8(self, _value: i8) -> Result<()> {
514        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
515    }
516
517    fn serialize_i16(self, _value: i16) -> Result<()> {
518        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
519    }
520
521    fn serialize_i32(self, _value: i32) -> Result<()> {
522        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
523    }
524
525    fn serialize_i64(self, _value: i64) -> Result<()> {
526        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
527    }
528
529    fn serialize_u8(self, _value: u8) -> Result<()> {
530        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
531    }
532
533    fn serialize_u16(self, _value: u16) -> Result<()> {
534        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
535    }
536
537    fn serialize_u32(self, _value: u32) -> Result<()> {
538        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
539    }
540
541    fn serialize_u64(self, _value: u64) -> Result<()> {
542        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
543    }
544
545    fn serialize_f32(self, _value: f32) -> Result<()> {
546        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
547    }
548
549    fn serialize_f64(self, _value: f64) -> Result<()> {
550        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
551    }
552
553    fn serialize_char(self, _value: char) -> Result<()> {
554        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
555    }
556
557    fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
558        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
559    }
560
561    fn serialize_unit(self) -> Result<()> {
562        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
563    }
564
565    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
566        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
567    }
568
569    fn serialize_unit_variant(
570        self,
571        _name: &'static str,
572        _variant_index: u32,
573        _variant: &'static str,
574    ) -> Result<()> {
575        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
576    }
577
578    fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<()>
579    where
580        T: ?Sized + ser::Serialize,
581    {
582        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
583    }
584
585    fn serialize_newtype_variant<T>(
586        self,
587        _name: &'static str,
588        _variant_index: u32,
589        _variant: &'static str,
590        _value: &T,
591    ) -> Result<()>
592    where
593        T: ?Sized + ser::Serialize,
594    {
595        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
596    }
597
598    fn serialize_none(self) -> Result<()> {
599        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
600    }
601
602    fn serialize_some<T>(self, _value: &T) -> Result<()>
603    where
604        T: ?Sized + ser::Serialize,
605    {
606        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
607    }
608
609    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeStruct> {
610        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
611    }
612
613    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
614        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
615    }
616
617    fn serialize_tuple_struct(
618        self,
619        _name: &'static str,
620        _len: usize,
621    ) -> Result<Self::SerializeTupleStruct> {
622        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
623    }
624
625    fn serialize_tuple_variant(
626        self,
627        _name: &'static str,
628        _variant_index: u32,
629        _variant: &'static str,
630        _len: usize,
631    ) -> Result<Self::SerializeTupleVariant> {
632        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
633    }
634
635    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
636        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
637    }
638
639    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
640        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
641    }
642
643    fn serialize_struct_variant(
644        self,
645        _name: &'static str,
646        _variant_index: u32,
647        _variant: &'static str,
648        _len: usize,
649    ) -> Result<Self::SerializeStructVariant> {
650        Err(Error::Syntax(ErrorCode::KeyMustBeAString, 0, 0))
651    }
652}
653
654/// This trait abstracts away serializing the JSON control characters
655pub trait Formatter {
656    /// Called when serializing a '{' or '['.
657    fn open<W>(&mut self, writer: &mut W, ch: u8) -> Result<()>
658    where
659        W: io::Write;
660
661    /// Called when serializing a ','.
662    fn comma<W>(&mut self, writer: &mut W, first: bool) -> Result<()>
663    where
664        W: io::Write;
665
666    /// Called when serializing a ':'.
667    fn colon<W>(&mut self, writer: &mut W) -> Result<()>
668    where
669        W: io::Write;
670
671    /// Called when serializing a '}' or ']'.
672    fn close<W>(&mut self, writer: &mut W, ch: u8) -> Result<()>
673    where
674        W: io::Write;
675
676    /// Newline with indent.
677    fn newline<W>(&mut self, writer: &mut W, add_indent: i32) -> Result<()>
678    where
679        W: io::Write;
680
681    /// Start a value.
682    fn start_value<W>(&mut self, writer: &mut W) -> Result<()>
683    where
684        W: io::Write;
685}
686
687struct HjsonFormatter<'a> {
688    current_indent: usize,
689    current_is_array: bool,
690    stack: Vec<bool>,
691    at_colon: bool,
692    indent: &'a [u8],
693    braces_same_line: bool,
694}
695
696impl<'a> HjsonFormatter<'a> {
697    /// Construct a formatter that defaults to using two spaces for indentation.
698    pub fn new() -> Self {
699        HjsonFormatter::with_indent(b"  ")
700    }
701
702    /// Construct a formatter that uses the `indent` string for indentation.
703    pub fn with_indent(indent: &'a [u8]) -> Self {
704        HjsonFormatter {
705            current_indent: 0,
706            current_is_array: false,
707            stack: Vec::new(),
708            at_colon: false,
709            indent,
710            braces_same_line: false,
711        }
712    }
713}
714
715impl<'a> Formatter for HjsonFormatter<'a> {
716    fn open<W>(&mut self, writer: &mut W, ch: u8) -> Result<()>
717    where
718        W: io::Write,
719    {
720        if self.current_indent > 0 && !self.current_is_array && !self.braces_same_line {
721            self.newline(writer, 0)?;
722        } else {
723            self.start_value(writer)?;
724        }
725        self.current_indent += 1;
726        self.stack.push(self.current_is_array);
727        self.current_is_array = ch == b'[';
728        writer.write_all(&[ch]).map_err(From::from)
729    }
730
731    fn comma<W>(&mut self, writer: &mut W, _: bool) -> Result<()>
732    where
733        W: io::Write,
734    {
735        writer.write_all(b"\n")?;
736        indent(writer, self.current_indent, self.indent)
737    }
738
739    fn colon<W>(&mut self, writer: &mut W) -> Result<()>
740    where
741        W: io::Write,
742    {
743        self.at_colon = !self.braces_same_line;
744        writer
745            .write_all(if self.braces_same_line { b": " } else { b":" })
746            .map_err(From::from)
747    }
748
749    fn close<W>(&mut self, writer: &mut W, ch: u8) -> Result<()>
750    where
751        W: io::Write,
752    {
753        self.current_indent -= 1;
754        self.current_is_array = self.stack.pop().unwrap();
755        writer.write_all(b"\n")?;
756        indent(writer, self.current_indent, self.indent)?;
757        writer.write_all(&[ch]).map_err(From::from)
758    }
759
760    fn newline<W>(&mut self, writer: &mut W, add_indent: i32) -> Result<()>
761    where
762        W: io::Write,
763    {
764        self.at_colon = false;
765        writer.write_all(b"\n")?;
766        let ii = self.current_indent as i32 + add_indent;
767        indent(writer, if ii < 0 { 0 } else { ii as usize }, self.indent)
768    }
769
770    fn start_value<W>(&mut self, writer: &mut W) -> Result<()>
771    where
772        W: io::Write,
773    {
774        if self.at_colon {
775            self.at_colon = false;
776            writer.write_all(b" ")?;
777        }
778        Ok(())
779    }
780}
781
782/// Serializes and escapes a `&[u8]` into a Hjson string.
783#[inline]
784pub fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> Result<()>
785where
786    W: io::Write,
787{
788    wr.write_all(b"\"")?;
789
790    let mut start = 0;
791
792    for (i, byte) in bytes.iter().enumerate() {
793        let escaped = match *byte {
794            b'"' => b"\\\"",
795            b'\\' => b"\\\\",
796            b'\x08' => b"\\b",
797            b'\x0c' => b"\\f",
798            b'\n' => b"\\n",
799            b'\r' => b"\\r",
800            b'\t' => b"\\t",
801            _ => {
802                continue;
803            }
804        };
805
806        if start < i {
807            wr.write_all(&bytes[start..i])?;
808        }
809
810        wr.write_all(escaped)?;
811
812        start = i + 1;
813    }
814
815    if start != bytes.len() {
816        wr.write_all(&bytes[start..])?;
817    }
818
819    wr.write_all(b"\"")?;
820    Ok(())
821}
822
823/// Serializes and escapes a `&str` into a Hjson string.
824#[inline]
825pub fn quote_str<W, F>(wr: &mut W, formatter: &mut F, value: &str) -> Result<()>
826where
827    W: io::Write,
828    F: Formatter,
829{
830    lazy_static! {
831        // NEEDS_ESCAPE tests if the string can be written without escapes
832        static ref NEEDS_ESCAPE: Regex = Regex::new("[\\\\\"\x00-\x1f\x7f-\u{9f}\u{00ad}\u{0600}-\u{0604}\u{070f}\u{17b4}\u{17b5}\u{200c}-\u{200f}\u{2028}-\u{202f}\u{2060}-\u{206f}\u{feff}\u{fff0}-\u{ffff}]").unwrap();
833        // NEEDS_QUOTES tests if the string can be written as a quoteless string (includes needsEscape but without \\ and \")
834        static ref NEEDS_QUOTES: Regex = Regex::new("^\\s|^\"|^'''|^#|^/\\*|^//|^\\{|^\\}|^\\[|^\\]|^:|^,|\\s$|[\x00-\x1f\x7f-\u{9f}\u{00ad}\u{0600}-\u{0604}\u{070f}\u{17b4}\u{17b5}\u{200c}-\u{200f}\u{2028}-\u{202f}\u{2060}-\u{206f}\u{feff}\u{fff0}-\u{ffff}]").unwrap();
835        // NEEDS_ESCAPEML tests if the string can be written as a multiline string (includes needsEscape but without \n, \r, \\ and \")
836        static ref NEEDS_ESCAPEML: Regex = Regex::new("'''|[\x00-\x09\x0b\x0c\x0e-\x1f\x7f-\u{9f}\u{00ad}\u{0600}-\u{0604}\u{070f}\u{17b4}\u{17b5}\u{200c}-\u{200f}\u{2028}-\u{202f}\u{2060}-\u{206f}\u{feff}\u{fff0}-\u{ffff}]").unwrap();
837        // starts with a keyword and optionally is followed by a comment
838        static ref STARTS_WITH_KEYWORD: Regex = Regex::new(r#"^(true|false|null)\s*((,|\]|\}|#|//|/\*).*)?$"#).unwrap();
839    }
840
841    if value.is_empty() {
842        formatter.start_value(wr)?;
843        return escape_bytes(wr, value.as_bytes());
844    }
845
846    // Check if we can insert this string without quotes
847    // see hjson syntax (must not parse as true, false, null or number)
848
849    let mut pn = ParseNumber::new(value.bytes());
850    let is_number = pn.parse(true).is_ok();
851
852    if is_number || NEEDS_QUOTES.is_match(value) || STARTS_WITH_KEYWORD.is_match(value) {
853        // First check if the string can be expressed in multiline format or
854        // we must replace the offending characters with safe escape sequences.
855
856        if NEEDS_ESCAPE.is_match(value) && !NEEDS_ESCAPEML.is_match(value)
857        /* && !isRootObject */
858        {
859            ml_str(wr, formatter, value)
860        } else {
861            formatter.start_value(wr)?;
862            escape_bytes(wr, value.as_bytes())
863        }
864    } else {
865        // without quotes
866        formatter.start_value(wr)?;
867        wr.write_all(value.as_bytes()).map_err(From::from)
868    }
869}
870
871/// Serializes and escapes a `&str` into a multiline Hjson string.
872pub fn ml_str<W, F>(wr: &mut W, formatter: &mut F, value: &str) -> Result<()>
873where
874    W: io::Write,
875    F: Formatter,
876{
877    // wrap the string into the ''' (multiline) format
878
879    let a: Vec<&str> = value.split('\n').collect();
880
881    if a.len() == 1 {
882        // The string contains only a single line. We still use the multiline
883        // format as it avoids escaping the \ character (e.g. when used in a
884        // regex).
885        formatter.start_value(wr)?;
886        wr.write_all(b"'''")?;
887        wr.write_all(a[0].as_bytes())?;
888        wr.write_all(b"'''")?;
889    } else {
890        formatter.newline(wr, 1)?;
891        wr.write_all(b"'''")?;
892        for line in a {
893            formatter.newline(wr, if line.is_empty() { -999 } else { 1 })?;
894            wr.write_all(line.as_bytes())?;
895        }
896        formatter.newline(wr, 1)?;
897        wr.write_all(b"'''")?;
898    }
899    Ok(())
900}
901
902/// Serializes and escapes a `&str` into a Hjson key.
903#[inline]
904pub fn escape_key<W>(wr: &mut W, value: &str) -> Result<()>
905where
906    W: io::Write,
907{
908    lazy_static! {
909        static ref NEEDS_ESCAPE_NAME: Regex =
910            Regex::new(r#"[,\{\[\}\]\s:#"]|//|/\*|'''|^$"#).unwrap();
911    }
912
913    // Check if we can insert this name without quotes
914    if NEEDS_ESCAPE_NAME.is_match(value) {
915        escape_bytes(wr, value.as_bytes()).map_err(From::from)
916    } else {
917        wr.write_all(value.as_bytes()).map_err(From::from)
918    }
919}
920
921#[inline]
922fn escape_char<W>(wr: &mut W, value: char) -> Result<()>
923where
924    W: io::Write,
925{
926    // FIXME: this allocation is required in order to be compatible with stable
927    // rust, which doesn't support encoding a `char` into a stack buffer.
928    let mut s = String::new();
929    s.push(value);
930    escape_bytes(wr, s.as_bytes())
931}
932
933fn fmt_f32_or_null<W>(wr: &mut W, value: f32) -> Result<()>
934where
935    W: io::Write,
936{
937    match value.classify() {
938        FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null")?,
939        _ => wr.write_all(fmt_small(value).as_bytes())?,
940    }
941
942    Ok(())
943}
944
945fn fmt_f64_or_null<W>(wr: &mut W, value: f64) -> Result<()>
946where
947    W: io::Write,
948{
949    match value.classify() {
950        FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null")?,
951        _ => wr.write_all(fmt_small(value).as_bytes())?,
952    }
953
954    Ok(())
955}
956
957fn indent<W>(wr: &mut W, n: usize, s: &[u8]) -> Result<()>
958where
959    W: io::Write,
960{
961    for _ in 0..n {
962        wr.write_all(s)?;
963    }
964
965    Ok(())
966}
967
968// format similar to es6
969fn fmt_small<N>(value: N) -> String
970where
971    N: Display + LowerExp,
972{
973    let f1 = format!("{}", value);
974    let f2 = format!("{:e}", value);
975    if f1.len() <= f2.len() + 1 {
976        f1
977    } else if !f2.contains("e-") {
978        f2.replace("e", "e+")
979    } else {
980        f2
981    }
982}
983
984/// Encode the specified struct into a Hjson `[u8]` writer.
985#[inline]
986pub fn to_writer<W, T>(writer: &mut W, value: &T) -> Result<()>
987where
988    W: io::Write,
989    T: ser::Serialize,
990{
991    let mut ser = Serializer::new(writer);
992    value.serialize(&mut ser)?;
993    Ok(())
994}
995
996/// Encode the specified struct into a Hjson `[u8]` buffer.
997#[inline]
998pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
999where
1000    T: ser::Serialize,
1001{
1002    // We are writing to a Vec, which doesn't fail. So we can ignore
1003    // the error.
1004    let mut writer = Vec::with_capacity(128);
1005    to_writer(&mut writer, value)?;
1006    Ok(writer)
1007}
1008
1009/// Encode the specified struct into a Hjson `String` buffer.
1010#[inline]
1011pub fn to_string<T>(value: &T) -> Result<String>
1012where
1013    T: ser::Serialize,
1014{
1015    let vec = to_vec(value)?;
1016    let string = String::from_utf8(vec)?;
1017    Ok(string)
1018}