serde_yaml/
ser.rs

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