serde_yaml/
ser.rs

1//! YAML Serialization
2//!
3//! This module provides YAML serialization with the type `Serializer`.
4
5use crate::error::{self, Error, ErrorImpl};
6use crate::libyaml;
7use crate::libyaml::emitter::{Emitter, Event, Mapping, Scalar, ScalarStyle, Sequence};
8use crate::value::tagged::{self, MaybeTag};
9use serde::de::Visitor;
10use serde::ser::{self, Serializer as _};
11use std::fmt::{self, Display};
12use std::io;
13use std::marker::PhantomData;
14use std::mem;
15use std::num;
16use std::str;
17
18type Result<T, E = Error> = std::result::Result<T, E>;
19
20/// A structure for serializing Rust values into YAML.
21///
22/// # Example
23///
24/// ```
25/// use anyhow::Result;
26/// use serde::Serialize;
27/// use std::collections::BTreeMap;
28///
29/// fn main() -> Result<()> {
30///     let mut buffer = Vec::new();
31///     let mut ser = serde_yaml::Serializer::new(&mut buffer);
32///
33///     let mut object = BTreeMap::new();
34///     object.insert("k", 107);
35///     object.serialize(&mut ser)?;
36///
37///     object.insert("J", 74);
38///     object.serialize(&mut ser)?;
39///
40///     assert_eq!(buffer, b"k: 107\n---\nJ: 74\nk: 107\n");
41///     Ok(())
42/// }
43/// ```
44pub struct Serializer<W> {
45    depth: usize,
46    state: State,
47    emitter: Emitter<'static>,
48    writer: PhantomData<W>,
49}
50
51enum State {
52    NothingInParticular,
53    CheckForTag,
54    CheckForDuplicateTag,
55    FoundTag(String),
56    AlreadyTagged,
57}
58
59impl<W> Serializer<W>
60where
61    W: io::Write,
62{
63    /// Creates a new YAML serializer.
64    pub fn new(writer: W) -> Self {
65        let mut emitter = Emitter::new({
66            let writer = Box::new(writer);
67            unsafe { mem::transmute::<Box<dyn io::Write>, Box<dyn io::Write>>(writer) }
68        });
69        emitter.emit(Event::StreamStart).unwrap();
70        Serializer {
71            depth: 0,
72            state: State::NothingInParticular,
73            emitter,
74            writer: PhantomData,
75        }
76    }
77
78    /// Calls [`.flush()`](io::Write::flush) on the underlying `io::Write`
79    /// object.
80    pub fn flush(&mut self) -> Result<()> {
81        self.emitter.flush()?;
82        Ok(())
83    }
84
85    /// Unwrap the underlying `io::Write` object from the `Serializer`.
86    pub fn into_inner(mut self) -> Result<W> {
87        self.emitter.emit(Event::StreamEnd)?;
88        self.emitter.flush()?;
89        let writer = self.emitter.into_inner();
90        Ok(*unsafe { Box::from_raw(Box::into_raw(writer).cast::<W>()) })
91    }
92
93    fn emit_scalar(&mut self, mut scalar: Scalar) -> Result<()> {
94        self.flush_mapping_start()?;
95        if let Some(tag) = self.take_tag() {
96            scalar.tag = Some(tag);
97        }
98        self.value_start()?;
99        self.emitter.emit(Event::Scalar(scalar))?;
100        self.value_end()
101    }
102
103    fn emit_sequence_start(&mut self) -> Result<()> {
104        self.flush_mapping_start()?;
105        self.value_start()?;
106        let tag = self.take_tag();
107        self.emitter.emit(Event::SequenceStart(Sequence { tag }))?;
108        Ok(())
109    }
110
111    fn emit_sequence_end(&mut self) -> Result<()> {
112        self.emitter.emit(Event::SequenceEnd)?;
113        self.value_end()
114    }
115
116    fn emit_mapping_start(&mut self) -> Result<()> {
117        self.flush_mapping_start()?;
118        self.value_start()?;
119        let tag = self.take_tag();
120        self.emitter.emit(Event::MappingStart(Mapping { tag }))?;
121        Ok(())
122    }
123
124    fn emit_mapping_end(&mut self) -> Result<()> {
125        self.emitter.emit(Event::MappingEnd)?;
126        self.value_end()
127    }
128
129    fn value_start(&mut self) -> Result<()> {
130        if self.depth == 0 {
131            self.emitter.emit(Event::DocumentStart)?;
132        }
133        self.depth += 1;
134        Ok(())
135    }
136
137    fn value_end(&mut self) -> Result<()> {
138        self.depth -= 1;
139        if self.depth == 0 {
140            self.emitter.emit(Event::DocumentEnd)?;
141        }
142        Ok(())
143    }
144
145    fn take_tag(&mut self) -> Option<String> {
146        let state = mem::replace(&mut self.state, State::NothingInParticular);
147        if let State::FoundTag(mut tag) = state {
148            if !tag.starts_with('!') {
149                tag.insert(0, '!');
150            }
151            Some(tag)
152        } else {
153            self.state = state;
154            None
155        }
156    }
157
158    fn flush_mapping_start(&mut self) -> Result<()> {
159        if let State::CheckForTag = self.state {
160            self.state = State::NothingInParticular;
161            self.emit_mapping_start()?;
162        } else if let State::CheckForDuplicateTag = self.state {
163            self.state = State::NothingInParticular;
164        }
165        Ok(())
166    }
167}
168
169impl<'a, W> ser::Serializer for &'a mut Serializer<W>
170where
171    W: io::Write,
172{
173    type Ok = ();
174    type Error = Error;
175
176    type SerializeSeq = Self;
177    type SerializeTuple = Self;
178    type SerializeTupleStruct = Self;
179    type SerializeTupleVariant = Self;
180    type SerializeMap = Self;
181    type SerializeStruct = Self;
182    type SerializeStructVariant = Self;
183
184    fn serialize_bool(self, v: bool) -> Result<()> {
185        self.emit_scalar(Scalar {
186            tag: None,
187            value: if v { "true" } else { "false" },
188            style: ScalarStyle::Plain,
189        })
190    }
191
192    fn serialize_i8(self, v: i8) -> Result<()> {
193        self.emit_scalar(Scalar {
194            tag: None,
195            value: itoa::Buffer::new().format(v),
196            style: ScalarStyle::Plain,
197        })
198    }
199
200    fn serialize_i16(self, v: i16) -> Result<()> {
201        self.emit_scalar(Scalar {
202            tag: None,
203            value: itoa::Buffer::new().format(v),
204            style: ScalarStyle::Plain,
205        })
206    }
207
208    fn serialize_i32(self, v: i32) -> Result<()> {
209        self.emit_scalar(Scalar {
210            tag: None,
211            value: itoa::Buffer::new().format(v),
212            style: ScalarStyle::Plain,
213        })
214    }
215
216    fn serialize_i64(self, v: i64) -> Result<()> {
217        self.emit_scalar(Scalar {
218            tag: None,
219            value: itoa::Buffer::new().format(v),
220            style: ScalarStyle::Plain,
221        })
222    }
223
224    fn serialize_i128(self, v: i128) -> Result<()> {
225        self.emit_scalar(Scalar {
226            tag: None,
227            value: itoa::Buffer::new().format(v),
228            style: ScalarStyle::Plain,
229        })
230    }
231
232    fn serialize_u8(self, v: u8) -> Result<()> {
233        self.emit_scalar(Scalar {
234            tag: None,
235            value: itoa::Buffer::new().format(v),
236            style: ScalarStyle::Plain,
237        })
238    }
239
240    fn serialize_u16(self, v: u16) -> Result<()> {
241        self.emit_scalar(Scalar {
242            tag: None,
243            value: itoa::Buffer::new().format(v),
244            style: ScalarStyle::Plain,
245        })
246    }
247
248    fn serialize_u32(self, v: u32) -> Result<()> {
249        self.emit_scalar(Scalar {
250            tag: None,
251            value: itoa::Buffer::new().format(v),
252            style: ScalarStyle::Plain,
253        })
254    }
255
256    fn serialize_u64(self, v: u64) -> Result<()> {
257        self.emit_scalar(Scalar {
258            tag: None,
259            value: itoa::Buffer::new().format(v),
260            style: ScalarStyle::Plain,
261        })
262    }
263
264    fn serialize_u128(self, v: u128) -> Result<()> {
265        self.emit_scalar(Scalar {
266            tag: None,
267            value: itoa::Buffer::new().format(v),
268            style: ScalarStyle::Plain,
269        })
270    }
271
272    fn serialize_f32(self, v: f32) -> Result<()> {
273        let mut buffer = ryu::Buffer::new();
274        self.emit_scalar(Scalar {
275            tag: None,
276            value: match v.classify() {
277                num::FpCategory::Infinite if v.is_sign_positive() => ".inf",
278                num::FpCategory::Infinite => "-.inf",
279                num::FpCategory::Nan => ".nan",
280                _ => buffer.format_finite(v),
281            },
282            style: ScalarStyle::Plain,
283        })
284    }
285
286    fn serialize_f64(self, v: f64) -> Result<()> {
287        let mut buffer = ryu::Buffer::new();
288        self.emit_scalar(Scalar {
289            tag: None,
290            value: match v.classify() {
291                num::FpCategory::Infinite if v.is_sign_positive() => ".inf",
292                num::FpCategory::Infinite => "-.inf",
293                num::FpCategory::Nan => ".nan",
294                _ => buffer.format_finite(v),
295            },
296            style: ScalarStyle::Plain,
297        })
298    }
299
300    fn serialize_char(self, value: char) -> Result<()> {
301        self.emit_scalar(Scalar {
302            tag: None,
303            value: value.encode_utf8(&mut [0u8; 4]),
304            style: ScalarStyle::SingleQuoted,
305        })
306    }
307
308    fn serialize_str(self, value: &str) -> Result<()> {
309        struct InferScalarStyle;
310
311        impl<'de> Visitor<'de> for InferScalarStyle {
312            type Value = ScalarStyle;
313
314            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
315                formatter.write_str("I wonder")
316            }
317
318            fn visit_bool<E>(self, _v: bool) -> Result<Self::Value, E> {
319                Ok(ScalarStyle::SingleQuoted)
320            }
321
322            fn visit_i64<E>(self, _v: i64) -> Result<Self::Value, E> {
323                Ok(ScalarStyle::SingleQuoted)
324            }
325
326            fn visit_i128<E>(self, _v: i128) -> Result<Self::Value, E> {
327                Ok(ScalarStyle::SingleQuoted)
328            }
329
330            fn visit_u64<E>(self, _v: u64) -> Result<Self::Value, E> {
331                Ok(ScalarStyle::SingleQuoted)
332            }
333
334            fn visit_u128<E>(self, _v: u128) -> Result<Self::Value, E> {
335                Ok(ScalarStyle::SingleQuoted)
336            }
337
338            fn visit_f64<E>(self, _v: f64) -> Result<Self::Value, E> {
339                Ok(ScalarStyle::SingleQuoted)
340            }
341
342            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
343                Ok(if crate::de::digits_but_not_number(v) {
344                    ScalarStyle::SingleQuoted
345                } else {
346                    ScalarStyle::Any
347                })
348            }
349
350            fn visit_unit<E>(self) -> Result<Self::Value, E> {
351                Ok(ScalarStyle::SingleQuoted)
352            }
353        }
354
355        let style = if value.contains('\n') {
356            ScalarStyle::Literal
357        } else {
358            let result = crate::de::visit_untagged_scalar(
359                InferScalarStyle,
360                value,
361                None,
362                libyaml::parser::ScalarStyle::Plain,
363            );
364            result.unwrap_or(ScalarStyle::Any)
365        };
366
367        self.emit_scalar(Scalar {
368            tag: None,
369            value,
370            style,
371        })
372    }
373
374    fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
375        Err(error::new(ErrorImpl::BytesUnsupported))
376    }
377
378    fn serialize_unit(self) -> Result<()> {
379        self.emit_scalar(Scalar {
380            tag: None,
381            value: "null",
382            style: ScalarStyle::Plain,
383        })
384    }
385
386    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
387        self.serialize_unit()
388    }
389
390    fn serialize_unit_variant(
391        self,
392        _name: &'static str,
393        _variant_index: u32,
394        variant: &'static str,
395    ) -> Result<()> {
396        self.serialize_str(variant)
397    }
398
399    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
400    where
401        T: ?Sized + ser::Serialize,
402    {
403        value.serialize(self)
404    }
405
406    fn serialize_newtype_variant<T>(
407        self,
408        _name: &'static str,
409        _variant_index: u32,
410        variant: &'static str,
411        value: &T,
412    ) -> Result<()>
413    where
414        T: ?Sized + ser::Serialize,
415    {
416        if let State::FoundTag(_) = self.state {
417            return Err(error::new(ErrorImpl::SerializeNestedEnum));
418        }
419        self.state = State::FoundTag(variant.to_owned());
420        value.serialize(&mut *self)
421    }
422
423    fn serialize_none(self) -> Result<()> {
424        self.serialize_unit()
425    }
426
427    fn serialize_some<V>(self, value: &V) -> Result<()>
428    where
429        V: ?Sized + ser::Serialize,
430    {
431        value.serialize(self)
432    }
433
434    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
435        self.emit_sequence_start()?;
436        Ok(self)
437    }
438
439    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
440        self.emit_sequence_start()?;
441        Ok(self)
442    }
443
444    fn serialize_tuple_struct(
445        self,
446        _name: &'static str,
447        _len: usize,
448    ) -> Result<Self::SerializeTupleStruct> {
449        self.emit_sequence_start()?;
450        Ok(self)
451    }
452
453    fn serialize_tuple_variant(
454        self,
455        _enm: &'static str,
456        _idx: u32,
457        variant: &'static str,
458        _len: usize,
459    ) -> Result<Self::SerializeTupleVariant> {
460        if let State::FoundTag(_) = self.state {
461            return Err(error::new(ErrorImpl::SerializeNestedEnum));
462        }
463        self.state = State::FoundTag(variant.to_owned());
464        self.emit_sequence_start()?;
465        Ok(self)
466    }
467
468    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
469        if len == Some(1) {
470            self.state = if let State::FoundTag(_) = self.state {
471                self.emit_mapping_start()?;
472                State::CheckForDuplicateTag
473            } else {
474                State::CheckForTag
475            };
476        } else {
477            self.emit_mapping_start()?;
478        }
479        Ok(self)
480    }
481
482    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
483        self.emit_mapping_start()?;
484        Ok(self)
485    }
486
487    fn serialize_struct_variant(
488        self,
489        _enm: &'static str,
490        _idx: u32,
491        variant: &'static str,
492        _len: usize,
493    ) -> Result<Self::SerializeStructVariant> {
494        if let State::FoundTag(_) = self.state {
495            return Err(error::new(ErrorImpl::SerializeNestedEnum));
496        }
497        self.state = State::FoundTag(variant.to_owned());
498        self.emit_mapping_start()?;
499        Ok(self)
500    }
501
502    fn collect_str<T>(self, value: &T) -> Result<Self::Ok>
503    where
504        T: ?Sized + Display,
505    {
506        let string = if let State::CheckForTag | State::CheckForDuplicateTag = self.state {
507            match tagged::check_for_tag(value) {
508                MaybeTag::NotTag(string) => string,
509                MaybeTag::Tag(string) => {
510                    return if let State::CheckForDuplicateTag = self.state {
511                        Err(error::new(ErrorImpl::SerializeNestedEnum))
512                    } else {
513                        self.state = State::FoundTag(string);
514                        Ok(())
515                    };
516                }
517            }
518        } else {
519            value.to_string()
520        };
521
522        self.serialize_str(&string)
523    }
524}
525
526impl<'a, W> ser::SerializeSeq for &'a mut Serializer<W>
527where
528    W: io::Write,
529{
530    type Ok = ();
531    type Error = Error;
532
533    fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
534    where
535        T: ?Sized + ser::Serialize,
536    {
537        elem.serialize(&mut **self)
538    }
539
540    fn end(self) -> Result<()> {
541        self.emit_sequence_end()
542    }
543}
544
545impl<'a, W> ser::SerializeTuple for &'a mut Serializer<W>
546where
547    W: io::Write,
548{
549    type Ok = ();
550    type Error = Error;
551
552    fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
553    where
554        T: ?Sized + ser::Serialize,
555    {
556        elem.serialize(&mut **self)
557    }
558
559    fn end(self) -> Result<()> {
560        self.emit_sequence_end()
561    }
562}
563
564impl<'a, W> ser::SerializeTupleStruct for &'a mut Serializer<W>
565where
566    W: io::Write,
567{
568    type Ok = ();
569    type Error = Error;
570
571    fn serialize_field<V>(&mut self, value: &V) -> Result<()>
572    where
573        V: ?Sized + ser::Serialize,
574    {
575        value.serialize(&mut **self)
576    }
577
578    fn end(self) -> Result<()> {
579        self.emit_sequence_end()
580    }
581}
582
583impl<'a, W> ser::SerializeTupleVariant for &'a mut Serializer<W>
584where
585    W: io::Write,
586{
587    type Ok = ();
588    type Error = Error;
589
590    fn serialize_field<V>(&mut self, v: &V) -> Result<()>
591    where
592        V: ?Sized + ser::Serialize,
593    {
594        v.serialize(&mut **self)
595    }
596
597    fn end(self) -> Result<()> {
598        self.emit_sequence_end()
599    }
600}
601
602impl<'a, W> ser::SerializeMap for &'a mut Serializer<W>
603where
604    W: io::Write,
605{
606    type Ok = ();
607    type Error = Error;
608
609    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
610    where
611        T: ?Sized + ser::Serialize,
612    {
613        self.flush_mapping_start()?;
614        key.serialize(&mut **self)
615    }
616
617    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
618    where
619        T: ?Sized + ser::Serialize,
620    {
621        value.serialize(&mut **self)
622    }
623
624    fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error>
625    where
626        K: ?Sized + ser::Serialize,
627        V: ?Sized + ser::Serialize,
628    {
629        key.serialize(&mut **self)?;
630        let tagged = matches!(self.state, State::FoundTag(_));
631        value.serialize(&mut **self)?;
632        if tagged {
633            self.state = State::AlreadyTagged;
634        }
635        Ok(())
636    }
637
638    fn end(self) -> Result<()> {
639        if let State::CheckForTag = self.state {
640            self.emit_mapping_start()?;
641        }
642        if !matches!(self.state, State::AlreadyTagged) {
643            self.emit_mapping_end()?;
644        }
645        self.state = State::NothingInParticular;
646        Ok(())
647    }
648}
649
650impl<'a, W> ser::SerializeStruct for &'a mut Serializer<W>
651where
652    W: io::Write,
653{
654    type Ok = ();
655    type Error = Error;
656
657    fn serialize_field<V>(&mut self, key: &'static str, value: &V) -> Result<()>
658    where
659        V: ?Sized + ser::Serialize,
660    {
661        self.serialize_str(key)?;
662        value.serialize(&mut **self)
663    }
664
665    fn end(self) -> Result<()> {
666        self.emit_mapping_end()
667    }
668}
669
670impl<'a, W> ser::SerializeStructVariant for &'a mut Serializer<W>
671where
672    W: io::Write,
673{
674    type Ok = ();
675    type Error = Error;
676
677    fn serialize_field<V>(&mut self, field: &'static str, v: &V) -> Result<()>
678    where
679        V: ?Sized + ser::Serialize,
680    {
681        self.serialize_str(field)?;
682        v.serialize(&mut **self)
683    }
684
685    fn end(self) -> Result<()> {
686        self.emit_mapping_end()
687    }
688}
689
690/// Serialize the given data structure as YAML into the IO stream.
691///
692/// Serialization can fail if `T`'s implementation of `Serialize` decides to
693/// return an error.
694pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
695where
696    W: io::Write,
697    T: ?Sized + ser::Serialize,
698{
699    let mut serializer = Serializer::new(writer);
700    value.serialize(&mut serializer)
701}
702
703/// Serialize the given data structure as a String of YAML.
704///
705/// Serialization can fail if `T`'s implementation of `Serialize` decides to
706/// return an error.
707pub fn to_string<T>(value: &T) -> Result<String>
708where
709    T: ?Sized + ser::Serialize,
710{
711    let mut vec = Vec::with_capacity(128);
712    to_writer(&mut vec, value)?;
713    String::from_utf8(vec).map_err(|error| error::new(ErrorImpl::FromUtf8(error)))
714}