summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde_yaml/src/ser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/serde_yaml/src/ser.rs')
-rw-r--r--third_party/rust/serde_yaml/src/ser.rs887
1 files changed, 887 insertions, 0 deletions
diff --git a/third_party/rust/serde_yaml/src/ser.rs b/third_party/rust/serde_yaml/src/ser.rs
new file mode 100644
index 0000000000..6ce5995dff
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/ser.rs
@@ -0,0 +1,887 @@
+//! YAML Serialization
+//!
+//! This module provides YAML serialization with the type `Serializer`.
+
+use crate::{error, Error, Result};
+use serde::ser;
+use std::{fmt, io, num, str};
+use yaml_rust::{yaml, Yaml, YamlEmitter};
+
+/// A structure for serializing Rust values into YAML.
+///
+/// # Example
+///
+/// ```
+/// use anyhow::Result;
+/// use serde::Serialize;
+/// use std::collections::BTreeMap;
+///
+/// fn main() -> Result<()> {
+/// let mut buffer = Vec::new();
+/// let mut ser = serde_yaml::Serializer::new(&mut buffer);
+///
+/// let mut object = BTreeMap::new();
+/// object.insert("k", 107);
+/// object.serialize(&mut ser)?;
+///
+/// object.insert("J", 74);
+/// object.serialize(&mut ser)?;
+///
+/// assert_eq!(buffer, b"---\nk: 107\n...\n---\nJ: 74\nk: 107\n");
+/// Ok(())
+/// }
+/// ```
+pub struct Serializer<W> {
+ documents: usize,
+ writer: W,
+}
+
+impl<W> Serializer<W>
+where
+ W: io::Write,
+{
+ /// Creates a new YAML serializer.
+ pub fn new(writer: W) -> Self {
+ Serializer {
+ documents: 0,
+ writer,
+ }
+ }
+
+ /// Calls [`.flush()`](io::Write::flush) on the underlying `io::Write`
+ /// object.
+ pub fn flush(&mut self) -> io::Result<()> {
+ self.writer.flush()
+ }
+
+ /// Unwrap the underlying `io::Write` object from the `Serializer`.
+ pub fn into_inner(self) -> W {
+ self.writer
+ }
+
+ fn write(&mut self, doc: Yaml) -> Result<()> {
+ if self.documents > 0 {
+ self.writer.write_all(b"...\n").map_err(error::io)?;
+ }
+ self.documents += 1;
+ let mut writer_adapter = FmtToIoWriter {
+ writer: &mut self.writer,
+ };
+ YamlEmitter::new(&mut writer_adapter)
+ .dump(&doc)
+ .map_err(error::emitter)?;
+ writer_adapter.writer.write_all(b"\n").map_err(error::io)?;
+ Ok(())
+ }
+}
+
+impl<'a, W> ser::Serializer for &'a mut Serializer<W>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ type SerializeSeq = ThenWrite<'a, W, SerializeArray>;
+ type SerializeTuple = ThenWrite<'a, W, SerializeArray>;
+ type SerializeTupleStruct = ThenWrite<'a, W, SerializeArray>;
+ type SerializeTupleVariant = ThenWrite<'a, W, SerializeTupleVariant>;
+ type SerializeMap = ThenWrite<'a, W, SerializeMap>;
+ type SerializeStruct = ThenWrite<'a, W, SerializeStruct>;
+ type SerializeStructVariant = ThenWrite<'a, W, SerializeStructVariant>;
+
+ fn serialize_bool(self, v: bool) -> Result<()> {
+ let doc = SerializerToYaml.serialize_bool(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i8(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i16(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i32(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i64(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i128(self, v: i128) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i128(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u8(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u16(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u32(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u64(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u128(self, v: u128) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u128(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<()> {
+ let doc = SerializerToYaml.serialize_f32(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<()> {
+ let doc = SerializerToYaml.serialize_f64(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_char(self, value: char) -> Result<()> {
+ let doc = SerializerToYaml.serialize_char(value)?;
+ self.write(doc)
+ }
+
+ fn serialize_str(self, value: &str) -> Result<()> {
+ let doc = SerializerToYaml.serialize_str(value)?;
+ self.write(doc)
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<()> {
+ let doc = SerializerToYaml.serialize_bytes(value)?;
+ self.write(doc)
+ }
+
+ fn serialize_unit(self) -> Result<()> {
+ let doc = SerializerToYaml.serialize_unit()?;
+ self.write(doc)
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
+ let doc = SerializerToYaml.serialize_unit_struct(name)?;
+ self.write(doc)
+ }
+
+ fn serialize_unit_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<()> {
+ let doc = SerializerToYaml.serialize_unit_variant(name, variant_index, variant)?;
+ self.write(doc)
+ }
+
+ fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ let doc = SerializerToYaml.serialize_newtype_struct(name, value)?;
+ self.write(doc)
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ let doc =
+ SerializerToYaml.serialize_newtype_variant(name, variant_index, variant, value)?;
+ self.write(doc)
+ }
+
+ fn serialize_none(self) -> Result<()> {
+ let doc = SerializerToYaml.serialize_none()?;
+ self.write(doc)
+ }
+
+ fn serialize_some<V>(self, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ let doc = SerializerToYaml.serialize_some(value)?;
+ self.write(doc)
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
+ let delegate = SerializerToYaml.serialize_seq(len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
+ let delegate = SerializerToYaml.serialize_tuple(len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ let delegate = SerializerToYaml.serialize_tuple_struct(name, len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ enm: &'static str,
+ idx: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ let delegate = SerializerToYaml.serialize_tuple_variant(enm, idx, variant, len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
+ let delegate = SerializerToYaml.serialize_map(len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
+ let delegate = SerializerToYaml.serialize_struct(name, len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ enm: &'static str,
+ idx: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ let delegate = SerializerToYaml.serialize_struct_variant(enm, idx, variant, len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+}
+
+pub struct ThenWrite<'a, W, D> {
+ serializer: &'a mut Serializer<W>,
+ delegate: D,
+}
+
+impl<'a, W, D> ThenWrite<'a, W, D> {
+ fn new(serializer: &'a mut Serializer<W>, delegate: D) -> Self {
+ ThenWrite {
+ serializer,
+ delegate,
+ }
+ }
+}
+
+impl<'a, W> ser::SerializeSeq for ThenWrite<'a, W, SerializeArray>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_element(elem)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeTuple for ThenWrite<'a, W, SerializeArray>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_element(elem)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeTupleStruct for ThenWrite<'a, W, SerializeArray>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_field(value)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeTupleVariant for ThenWrite<'a, W, SerializeTupleVariant>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, v: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_field(v)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeMap for ThenWrite<'a, W, SerializeMap>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_key(key)
+ }
+
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_value(value)
+ }
+
+ fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
+ where
+ K: ?Sized + ser::Serialize,
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_entry(key, value)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeStruct for ThenWrite<'a, W, SerializeStruct>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, key: &'static str, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_field(key, value)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeStructVariant for ThenWrite<'a, W, SerializeStructVariant>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, field: &'static str, v: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_field(field, v)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+pub struct SerializerToYaml;
+
+impl ser::Serializer for SerializerToYaml {
+ type Ok = Yaml;
+ type Error = Error;
+
+ type SerializeSeq = SerializeArray;
+ type SerializeTuple = SerializeArray;
+ type SerializeTupleStruct = SerializeArray;
+ type SerializeTupleVariant = SerializeTupleVariant;
+ type SerializeMap = SerializeMap;
+ type SerializeStruct = SerializeStruct;
+ type SerializeStructVariant = SerializeStructVariant;
+
+ fn serialize_bool(self, v: bool) -> Result<Yaml> {
+ Ok(Yaml::Boolean(v))
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<Yaml> {
+ Ok(Yaml::Integer(v))
+ }
+
+ #[allow(clippy::cast_possible_truncation)]
+ fn serialize_i128(self, v: i128) -> Result<Yaml> {
+ if v <= i64::max_value() as i128 && v >= i64::min_value() as i128 {
+ self.serialize_i64(v as i64)
+ } else {
+ Ok(Yaml::Real(v.to_string()))
+ }
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<Yaml> {
+ if v <= i64::max_value() as u64 {
+ self.serialize_i64(v as i64)
+ } else {
+ Ok(Yaml::Real(v.to_string()))
+ }
+ }
+
+ #[allow(clippy::cast_possible_truncation)]
+ fn serialize_u128(self, v: u128) -> Result<Yaml> {
+ if v <= i64::max_value() as u128 {
+ self.serialize_i64(v as i64)
+ } else {
+ Ok(Yaml::Real(v.to_string()))
+ }
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<Yaml> {
+ Ok(Yaml::Real(match v.classify() {
+ num::FpCategory::Infinite if v.is_sign_positive() => ".inf".into(),
+ num::FpCategory::Infinite => "-.inf".into(),
+ num::FpCategory::Nan => ".nan".into(),
+ _ => ryu::Buffer::new().format_finite(v).into(),
+ }))
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<Yaml> {
+ Ok(Yaml::Real(match v.classify() {
+ num::FpCategory::Infinite if v.is_sign_positive() => ".inf".into(),
+ num::FpCategory::Infinite => "-.inf".into(),
+ num::FpCategory::Nan => ".nan".into(),
+ _ => ryu::Buffer::new().format_finite(v).into(),
+ }))
+ }
+
+ fn serialize_char(self, value: char) -> Result<Yaml> {
+ Ok(Yaml::String(value.to_string()))
+ }
+
+ fn serialize_str(self, value: &str) -> Result<Yaml> {
+ Ok(Yaml::String(value.to_owned()))
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<Yaml> {
+ let vec = value.iter().map(|&b| Yaml::Integer(b as i64)).collect();
+ Ok(Yaml::Array(vec))
+ }
+
+ fn serialize_unit(self) -> Result<Yaml> {
+ Ok(Yaml::Null)
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Yaml> {
+ self.serialize_unit()
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &str,
+ _variant_index: u32,
+ variant: &str,
+ ) -> Result<Yaml> {
+ Ok(Yaml::String(variant.to_owned()))
+ }
+
+ fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Yaml>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &str,
+ _variant_index: u32,
+ variant: &str,
+ value: &T,
+ ) -> Result<Yaml>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ Ok(singleton_hash(to_yaml(variant)?, to_yaml(value)?))
+ }
+
+ fn serialize_none(self) -> Result<Yaml> {
+ self.serialize_unit()
+ }
+
+ fn serialize_some<V>(self, value: &V) -> Result<Yaml>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<SerializeArray> {
+ let array = match len {
+ None => yaml::Array::new(),
+ Some(len) => yaml::Array::with_capacity(len),
+ };
+ Ok(SerializeArray { array })
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<SerializeArray> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SerializeArray> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _enum: &'static str,
+ _idx: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<SerializeTupleVariant> {
+ Ok(SerializeTupleVariant {
+ name: variant,
+ array: yaml::Array::with_capacity(len),
+ })
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<SerializeMap> {
+ Ok(SerializeMap {
+ hash: yaml::Hash::new(),
+ next_key: None,
+ })
+ }
+
+ fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<SerializeStruct> {
+ Ok(SerializeStruct {
+ hash: yaml::Hash::new(),
+ })
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _enum: &'static str,
+ _idx: u32,
+ variant: &'static str,
+ _len: usize,
+ ) -> Result<SerializeStructVariant> {
+ Ok(SerializeStructVariant {
+ name: variant,
+ hash: yaml::Hash::new(),
+ })
+ }
+}
+
+#[doc(hidden)]
+pub struct SerializeArray {
+ array: yaml::Array,
+}
+
+#[doc(hidden)]
+pub struct SerializeTupleVariant {
+ name: &'static str,
+ array: yaml::Array,
+}
+
+#[doc(hidden)]
+pub struct SerializeMap {
+ hash: yaml::Hash,
+ next_key: Option<yaml::Yaml>,
+}
+
+#[doc(hidden)]
+pub struct SerializeStruct {
+ hash: yaml::Hash,
+}
+
+#[doc(hidden)]
+pub struct SerializeStructVariant {
+ name: &'static str,
+ hash: yaml::Hash,
+}
+
+impl ser::SerializeSeq for SerializeArray {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.array.push(to_yaml(elem)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(Yaml::Array(self.array))
+ }
+}
+
+impl ser::SerializeTuple for SerializeArray {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, elem)
+ }
+
+ fn end(self) -> Result<Yaml> {
+ ser::SerializeSeq::end(self)
+ }
+}
+
+impl ser::SerializeTupleStruct for SerializeArray {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Yaml> {
+ ser::SerializeSeq::end(self)
+ }
+}
+
+impl ser::SerializeTupleVariant for SerializeTupleVariant {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, v: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.array.push(to_yaml(v)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(singleton_hash(to_yaml(self.name)?, Yaml::Array(self.array)))
+ }
+}
+
+impl ser::SerializeMap for SerializeMap {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.next_key = Some(to_yaml(key)?);
+ Ok(())
+ }
+
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ match self.next_key.take() {
+ Some(key) => self.hash.insert(key, to_yaml(value)?),
+ None => panic!("serialize_value called before serialize_key"),
+ };
+ Ok(())
+ }
+
+ fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
+ where
+ K: ?Sized + ser::Serialize,
+ V: ?Sized + ser::Serialize,
+ {
+ self.hash.insert(to_yaml(key)?, to_yaml(value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(Yaml::Hash(self.hash))
+ }
+}
+
+impl ser::SerializeStruct for SerializeStruct {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, key: &'static str, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.hash.insert(to_yaml(key)?, to_yaml(value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(Yaml::Hash(self.hash))
+ }
+}
+
+impl ser::SerializeStructVariant for SerializeStructVariant {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, field: &'static str, v: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.hash.insert(to_yaml(field)?, to_yaml(v)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(singleton_hash(to_yaml(self.name)?, Yaml::Hash(self.hash)))
+ }
+}
+
+/// Serialize the given data structure as YAML into the IO stream.
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// return an error.
+pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
+where
+ W: io::Write,
+ T: ?Sized + ser::Serialize,
+{
+ value.serialize(&mut Serializer::new(writer))
+}
+
+/// Serialize the given data structure as a YAML byte vector.
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// return an error.
+pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
+where
+ T: ?Sized + ser::Serialize,
+{
+ let mut vec = Vec::with_capacity(128);
+ to_writer(&mut vec, value)?;
+ Ok(vec)
+}
+
+/// Serialize the given data structure as a String of YAML.
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// return an error.
+pub fn to_string<T>(value: &T) -> Result<String>
+where
+ T: ?Sized + ser::Serialize,
+{
+ String::from_utf8(to_vec(value)?).map_err(error::string_utf8)
+}
+
+/// The yaml-rust library uses `fmt::Write` intead of `io::Write` so this is a
+/// simple adapter.
+struct FmtToIoWriter<W> {
+ writer: W,
+}
+
+impl<W> fmt::Write for FmtToIoWriter<W>
+where
+ W: io::Write,
+{
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ if self.writer.write_all(s.as_bytes()).is_err() {
+ return Err(fmt::Error);
+ }
+ Ok(())
+ }
+}
+
+fn to_yaml<T>(elem: T) -> Result<Yaml>
+where
+ T: ser::Serialize,
+{
+ elem.serialize(SerializerToYaml)
+}
+
+fn singleton_hash(k: Yaml, v: Yaml) -> Yaml {
+ let mut hash = yaml::Hash::new();
+ hash.insert(k, v);
+ Yaml::Hash(hash)
+}