Skip to main content

serde_yaml/
ser.rs

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