//! YAML Serialization
//!
//! This module provides YAML serialization with the type `Serializer`.
use crate ::error::{self , Error, ErrorImpl};
use crate ::libyaml;
use crate ::libyaml::emitter::{Emitter, Event, Mapping, Scalar, ScalarStyle, Sequence};
use crate ::value::tagged::{self , MaybeTag};
use serde::de::Visitor;
use serde::ser::{self , Serializer as _};
use std::fmt::{self , Display};
use std::io;
use std::marker::PhantomData;
use std::mem;
use std::num;
use std::str;
type Result<T, E = Error> = std::result::Result<T, E>;
/// 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"k: 107\n---\nJ: 74\nk: 107\n");
/// Ok(())
/// }
/// ```
pub struct Serializer<W> {
depth: usize,
state: State,
emitter: Emitter<'static>,
writer: PhantomData<W>,
}
enum State {
NothingInParticular,
CheckForTag,
CheckForDuplicateTag,
FoundTag(String),
AlreadyTagged,
}
impl <W> Serializer<W>
where
W: io::Write,
{
/// Creates a new YAML serializer.
pub fn new(writer: W) -> Self {
let mut emitter = Emitter::new({
let writer = Box ::new(writer);
unsafe { mem::transmute::<Box <dyn io::Write>, Box <dyn io::Write>>(writer) }
});
emitter.emit(Event::StreamStart).unwrap();
Serializer {
depth: 0 ,
state: State::NothingInParticular,
emitter,
writer: PhantomData,
}
}
/// Calls [`.flush()`](io::Write::flush) on the underlying `io::Write`
/// object.
pub fn flush(&mut self ) -> Result<()> {
self .emitter.flush()?;
Ok(())
}
/// Unwrap the underlying `io::Write` object from the `Serializer`.
pub fn into_inner(mut self ) -> Result<W> {
self .emitter.emit(Event::StreamEnd)?;
self .emitter.flush()?;
let writer = self .emitter.into_inner();
Ok(*unsafe { Box ::from_raw(Box ::into_raw(writer).cast::<W>()) })
}
fn emit_scalar(&mut self , mut scalar: Scalar) -> Result<()> {
self .flush_mapping_start()?;
if let Some(tag) = self .take_tag() {
scalar.tag = Some(tag);
}
self .value_start()?;
self .emitter.emit(Event::Scalar(scalar))?;
self .value_end()
}
fn emit_sequence_start(&mut self ) -> Result<()> {
self .flush_mapping_start()?;
self .value_start()?;
let tag = self .take_tag();
self .emitter.emit(Event::SequenceStart(Sequence { tag }))?;
Ok(())
}
fn emit_sequence_end(&mut self ) -> Result<()> {
self .emitter.emit(Event::SequenceEnd)?;
self .value_end()
}
fn emit_mapping_start(&mut self ) -> Result<()> {
self .flush_mapping_start()?;
self .value_start()?;
let tag = self .take_tag();
self .emitter.emit(Event::MappingStart(Mapping { tag }))?;
Ok(())
}
fn emit_mapping_end(&mut self ) -> Result<()> {
self .emitter.emit(Event::MappingEnd)?;
self .value_end()
}
fn value_start(&mut self ) -> Result<()> {
if self .depth == 0 {
self .emitter.emit(Event::DocumentStart)?;
}
self .depth += 1 ;
Ok(())
}
fn value_end(&mut self ) -> Result<()> {
self .depth -= 1 ;
if self .depth == 0 {
self .emitter.emit(Event::DocumentEnd)?;
}
Ok(())
}
fn take_tag(&mut self ) -> Option<String> {
let state = mem::replace(&mut self .state, State::NothingInParticular);
if let State::FoundTag(mut tag) = state {
if !tag.starts_with('!' ) {
tag.insert(0 , '!' );
}
Some(tag)
} else {
self .state = state;
None
}
}
fn flush_mapping_start(&mut self ) -> Result<()> {
if let State::CheckForTag = self .state {
self .state = State::NothingInParticular;
self .emit_mapping_start()?;
} else if let State::CheckForDuplicateTag = self .state {
self .state = State::NothingInParticular;
}
Ok(())
}
}
impl <'a, W> ser::Serializer for &' a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
type SerializeSeq = Self ;
type SerializeTuple = Self ;
type SerializeTupleStruct = Self ;
type SerializeTupleVariant = Self ;
type SerializeMap = Self ;
type SerializeStruct = Self ;
type SerializeStructVariant = Self ;
fn serialize_bool(self , v: bool) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: if v { "true" } else { "false" },
style: ScalarStyle::Plain,
})
}
fn serialize_i8(self , v: i8) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_i16(self , v: i16) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_i32(self , v: i32) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_i64(self , v: i64) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_i128(self , v: i128) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u8(self , v: u8) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u16(self , v: u16) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u32(self , v: u32) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u64(self , v: u64) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_u128(self , v: u128) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: itoa::Buffer::new().format(v),
style: ScalarStyle::Plain,
})
}
fn serialize_f32(self , v: f32) -> Result<()> {
let mut buffer = ryu::Buffer::new();
self .emit_scalar(Scalar {
tag: None,
value: match v.classify() {
num::FpCategory::Infinite if v.is_sign_positive() => ".inf" ,
num::FpCategory::Infinite => "-.inf" ,
num::FpCategory::Nan => ".nan" ,
_ => buffer.format_finite(v),
},
style: ScalarStyle::Plain,
})
}
fn serialize_f64(self , v: f64) -> Result<()> {
let mut buffer = ryu::Buffer::new();
self .emit_scalar(Scalar {
tag: None,
value: match v.classify() {
num::FpCategory::Infinite if v.is_sign_positive() => ".inf" ,
num::FpCategory::Infinite => "-.inf" ,
num::FpCategory::Nan => ".nan" ,
_ => buffer.format_finite(v),
},
style: ScalarStyle::Plain,
})
}
fn serialize_char(self , value: char) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: value.encode_utf8(&mut [0 u8; 4 ]),
style: ScalarStyle::SingleQuoted,
})
}
fn serialize_str(self , value: &str) -> Result<()> {
struct InferScalarStyle;
impl <'de> Visitor<' de> for InferScalarStyle {
type Value = ScalarStyle;
fn expecting(&self , formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("I wonder" )
}
fn visit_bool<E>(self , _v: bool) -> Result<Self ::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_i64<E>(self , _v: i64) -> Result<Self ::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_i128<E>(self , _v: i128) -> Result<Self ::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_u64<E>(self , _v: u64) -> Result<Self ::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_u128<E>(self , _v: u128) -> Result<Self ::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_f64<E>(self , _v: f64) -> Result<Self ::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
fn visit_str<E>(self , v: &str) -> Result<Self ::Value, E> {
Ok(if crate ::de::digits_but_not_number(v) {
ScalarStyle::SingleQuoted
} else {
ScalarStyle::Any
})
}
fn visit_unit<E>(self ) -> Result<Self ::Value, E> {
Ok(ScalarStyle::SingleQuoted)
}
}
let style = if value.contains('\n' ) {
ScalarStyle::Literal
} else {
let result = crate ::de::visit_untagged_scalar(
InferScalarStyle,
value,
None,
libyaml::parser::ScalarStyle::Plain,
);
result.unwrap_or(ScalarStyle::Any)
};
self .emit_scalar(Scalar {
tag: None,
value,
style,
})
}
fn serialize_bytes(self , _value: &[u8]) -> Result<()> {
Err(error::new(ErrorImpl::BytesUnsupported))
}
fn serialize_unit(self ) -> Result<()> {
self .emit_scalar(Scalar {
tag: None,
value: "null" ,
style: ScalarStyle::Plain,
})
}
fn serialize_unit_struct(self , _name: &'static str) -> Result<()> {
self .serialize_unit()
}
fn serialize_unit_variant(
self ,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<()> {
self .serialize_str(variant)
}
fn serialize_newtype_struct<T>(self , _name: &'static str, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
value.serialize(self )
}
fn serialize_newtype_variant<T>(
self ,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
if let State::FoundTag(_) = self .state {
return Err(error::new(ErrorImpl::SerializeNestedEnum));
}
self .state = State::FoundTag(variant.to_owned());
value.serialize(&mut *self )
}
fn serialize_none(self ) -> Result<()> {
self .serialize_unit()
}
fn serialize_some<V>(self , value: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
value.serialize(self )
}
fn serialize_seq(self , _len: Option<usize>) -> Result<Self ::SerializeSeq> {
self .emit_sequence_start()?;
Ok(self )
}
fn serialize_tuple(self , _len: usize) -> Result<Self ::SerializeTuple> {
self .emit_sequence_start()?;
Ok(self )
}
fn serialize_tuple_struct(
self ,
_name: &'static str,
_len: usize,
) -> Result<Self ::SerializeTupleStruct> {
self .emit_sequence_start()?;
Ok(self )
}
fn serialize_tuple_variant(
self ,
_enm: &'static str,
_idx: u32,
variant: &'static str,
_len: usize,
) -> Result<Self ::SerializeTupleVariant> {
if let State::FoundTag(_) = self .state {
return Err(error::new(ErrorImpl::SerializeNestedEnum));
}
self .state = State::FoundTag(variant.to_owned());
self .emit_sequence_start()?;
Ok(self )
}
fn serialize_map(self , len: Option<usize>) -> Result<Self ::SerializeMap> {
if len == Some(1 ) {
self .state = if let State::FoundTag(_) = self .state {
self .emit_mapping_start()?;
State::CheckForDuplicateTag
} else {
State::CheckForTag
};
} else {
self .emit_mapping_start()?;
}
Ok(self )
}
fn serialize_struct(self , _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
self .emit_mapping_start()?;
Ok(self )
}
fn serialize_struct_variant(
self ,
_enm: &'static str,
_idx: u32,
variant: &'static str,
_len: usize,
) -> Result<Self ::SerializeStructVariant> {
if let State::FoundTag(_) = self .state {
return Err(error::new(ErrorImpl::SerializeNestedEnum));
}
self .state = State::FoundTag(variant.to_owned());
self .emit_mapping_start()?;
Ok(self )
}
fn collect_str<T>(self , value: &T) -> Result<Self ::Ok>
where
T: ?Sized + Display,
{
let string = if let State::CheckForTag | State::CheckForDuplicateTag = self .state {
match tagged::check_for_tag(value) {
MaybeTag::NotTag(string) => string,
MaybeTag::Tag(string) => {
return if let State::CheckForDuplicateTag = self .state {
Err(error::new(ErrorImpl::SerializeNestedEnum))
} else {
self .state = State::FoundTag(string);
Ok(())
};
}
}
} else {
value.to_string()
};
self .serialize_str(&string)
}
}
impl <'a, W> ser::SerializeSeq for &' a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self , elem: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
elem.serialize(&mut **self )
}
fn end(self ) -> Result<()> {
self .emit_sequence_end()
}
}
impl <'a, W> ser::SerializeTuple for &' a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self , elem: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
elem.serialize(&mut **self )
}
fn end(self ) -> Result<()> {
self .emit_sequence_end()
}
}
impl <'a, W> ser::SerializeTupleStruct for &' a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<V>(&mut self , value: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
value.serialize(&mut **self )
}
fn end(self ) -> Result<()> {
self .emit_sequence_end()
}
}
impl <'a, W> ser::SerializeTupleVariant for &' a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_field<V>(&mut self , v: &V) -> Result<()>
where
V: ?Sized + ser::Serialize,
{
v.serialize(&mut **self )
}
fn end(self ) -> Result<()> {
self .emit_sequence_end()
}
}
impl <'a, W> ser::SerializeMap for &' a mut Serializer<W>
where
W: io::Write,
{
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self , key: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self .flush_mapping_start()?;
key.serialize(&mut **self )
}
fn serialize_value<T>(&mut self , value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
value.serialize(&mut **self )
}
fn serialize_entry<K, V>(&mut self , key: &K, value: &V) -> Result<(), Self ::Error>
where
K: ?Sized + ser::Serialize,
V: ?Sized + ser::Serialize,
{
key.serialize(&mut **self )?;
let tagged = matches!(self .state, State::FoundTag(_));
value.serialize(&mut **self )?;
if tagged {
self .state = State::AlreadyTagged;
}
Ok(())
}
fn end(self ) -> Result<()> {
if let State::CheckForTag = self .state {
self .emit_mapping_start()?;
}
if !matches!(self .state, State::AlreadyTagged) {
self .emit_mapping_end()?;
}
self .state = State::NothingInParticular;
Ok(())
}
}
impl <'a, W> ser::SerializeStruct for &' a mut Serializer<W>
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 .serialize_str(key)?;
value.serialize(&mut **self )
}
fn end(self ) -> Result<()> {
self .emit_mapping_end()
}
}
impl <'a, W> ser::SerializeStructVariant for &' a mut Serializer<W>
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 .serialize_str(field)?;
v.serialize(&mut **self )
}
fn end(self ) -> Result<()> {
self .emit_mapping_end()
}
}
/// 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,
{
let mut serializer = Serializer::new(writer);
value.serialize(&mut serializer)
}
/// 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,
{
let mut vec = Vec::with_capacity(128 );
to_writer(&mut vec, value)?;
String::from_utf8(vec).map_err(|error| error::new(ErrorImpl::FromUtf8(error)))
}
Messung V0.5 in Prozent C=82 H=96 G=89
¤ Dauer der Verarbeitung: 0.7 Sekunden
¤
*© Formatika GbR, Deutschland