yaml-peg 1.0.9

A YAML 1.2 parser using a greedy parsing algorithm with PEG atoms.
use super::SerdeError;
use crate::{dump, node, repr::Repr, Map, Node, NodeArc, NodeRc, Seq};
use alloc::string::String;
use core::marker::PhantomData;
use serde::{
    ser::{
        SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
        SerializeTupleStruct, SerializeTupleVariant,
    },
    serde_if_integer128, Serialize, Serializer,
};

macro_rules! impl_serializer {
    (@) => { () };
    (@$ty:ty, $name:ident) => { $name };
    ($(fn $method:ident$(($ty:ty))?)+) => {
        $(fn $method(self$(, v: $ty)?) -> Result<Self::Ok, Self::Error> {
            Ok(impl_serializer!(@$($ty, v)?).into())
        })+
    };
}

macro_rules! impl_end {
    (@ $self:ident) => {
        $self.0.into()
    };
    (@map $self:ident) => {
        node!(@{$self.1 => $self.0})
    };
}

macro_rules! impl_seq_serializer {
    ($(impl $trait:ident for $ty:ident => $method:ident $(($tt:tt))?)+) => {
        $(impl<R: Repr> $trait for $ty<R> {
            type Ok = Node<R>;
            type Error = SerdeError;

            fn $method<T>(&mut self, value: &T) -> Result<(), Self::Error>
            where
                T: Serialize + ?Sized,
            {
                self.0.push(value.serialize(NodeSerializer(PhantomData))?);
                Ok(())
            }

            fn end(self) -> Result<Self::Ok, Self::Error> {
                Ok(impl_end!(@$($tt)? self))
            }
        })+
    };
}

macro_rules! impl_map_serializer {
    ($(impl $trait:ident for $ty:ident $(($tt:tt))?)+) => {
        $(impl<R: Repr> $trait for $ty<R> {
            type Ok = Node<R>;
            type Error = SerdeError;

            fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
            where
                T: Serialize + ?Sized,
            {
                self.0.insert(
                    key.serialize(NodeSerializer(PhantomData))?,
                    value.serialize(NodeSerializer(PhantomData))?,
                );
                Ok(())
            }

            fn end(self) -> Result<Self::Ok, Self::Error> {
                Ok(impl_end!(@$($tt)? self))
            }
        })+
    };
}

/// Serialize data into [`Node`].
///
/// If a serializable data is provide,
/// it should be able to transform into YAML format.
///
/// ```
/// use serde::Serialize;
/// use yaml_peg::{serde::to_node, node};
///
/// #[derive(Serialize)]
/// struct Member<'a> {
///     name: &'a str,
///     married: bool,
///     age: u8,
/// }
///
/// let officer = Member { name: "Bob", married: true, age: 46 };
/// let officer_yaml = node!({
///     "name" => "Bob",
///     "married" => true,
///     "age" => 46,
/// });
/// assert_eq!(officer_yaml, to_node(&officer).unwrap());
/// ```
///
/// There is another version for multi-thread reference counter:
/// [`to_arc_node`].
pub fn to_node(any: &impl Serialize) -> Result<NodeRc, SerdeError> {
    any.serialize(NodeSerializer(PhantomData))
}

/// Serialize data into [`NodeArc`].
///
/// ```
/// use serde::Serialize;
/// use yaml_peg::{serde::to_arc_node, node};
///
/// #[derive(Serialize)]
/// struct Member<'a> {
///     name: &'a str,
///     married: bool,
///     age: u8,
/// }
///
/// let officer = Member { name: "Bob", married: true, age: 46 };
/// let officer_yaml = node!(arc{
///     "name" => "Bob",
///     "married" => true,
///     "age" => 46,
/// });
/// assert_eq!(officer_yaml, to_arc_node(officer).unwrap());
/// ```
///
/// There is another version for single-thread reference counter: [`to_node`].
pub fn to_arc_node(any: impl Serialize) -> Result<NodeArc, SerdeError> {
    any.serialize(NodeSerializer(PhantomData))
}

/// Serialize data into [`Node`] then dump into string.
///
/// ```
/// use serde::Serialize;
/// use yaml_peg::{dumper::NL, serde::to_string};
///
/// #[derive(Serialize)]
/// struct Member<'a> {
///     name: &'a str,
///     married: bool,
///     age: u8,
/// }
///
/// let officer = Member { name: "Bob", married: true, age: 46 };
/// let officer_doc = "\
/// name: Bob
/// married: true
/// age: 46
/// ";
/// assert_eq!(officer_doc.replace('\n', NL), to_string(&officer).unwrap());
/// ```
pub fn to_string(any: &impl Serialize) -> Result<String, SerdeError> {
    Ok(dump(&[to_node(any)?], &[]))
}

struct NodeSerializer<R: Repr>(PhantomData<R>);

impl<R: Repr> Serializer for NodeSerializer<R> {
    type Ok = Node<R>;
    type Error = SerdeError;
    type SerializeSeq = SeqSerializer<R>;
    type SerializeTuple = SeqSerializer<R>;
    type SerializeTupleStruct = SeqSerializer<R>;
    type SerializeTupleVariant = TupleVariant<R>;
    type SerializeMap = MapSerializer<R>;
    type SerializeStruct = StructSerializer<R>;
    type SerializeStructVariant = StructVariant<R>;

    impl_serializer! {
        fn serialize_bool(bool)
        fn serialize_i8(i8)
        fn serialize_i16(i16)
        fn serialize_i32(i32)
        fn serialize_i64(i64)
        fn serialize_u8(u8)
        fn serialize_u16(u16)
        fn serialize_u32(u32)
        fn serialize_u64(u64)
        fn serialize_f32(f32)
        fn serialize_f64(f64)
        fn serialize_char(char)
        fn serialize_str(&str)
        fn serialize_none
        fn serialize_unit
    }

    serde_if_integer128! {
        impl_serializer! {
            fn serialize_i128(i128)
            fn serialize_u128(u128)
        }
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
        Ok(v.iter().map(|b| Node::from(*b)).collect())
    }

    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
    where
        T: Serialize + ?Sized,
    {
        value.serialize(self)
    }

    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
        Ok(().into())
    }

    fn serialize_unit_variant(
        self,
        _name: &'static str,
        _variant_index: u32,
        variant: &'static str,
    ) -> Result<Self::Ok, Self::Error> {
        Ok(variant.into())
    }

    fn serialize_newtype_struct<T>(
        self,
        _name: &'static str,
        value: &T,
    ) -> Result<Self::Ok, Self::Error>
    where
        T: Serialize + ?Sized,
    {
        value.serialize(self)
    }

    fn serialize_newtype_variant<T>(
        self,
        _name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        value: &T,
    ) -> Result<Self::Ok, Self::Error>
    where
        T: Serialize + ?Sized,
    {
        Ok(node!(@{variant => value.serialize(NodeSerializer(PhantomData))?}))
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        let seq = match len {
            Some(n) => Seq::with_capacity(n),
            None => Seq::new(),
        };
        Ok(SeqSerializer(seq))
    }

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_struct(
        self,
        _name: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
        self.serialize_seq(Some(len))
    }

    fn serialize_tuple_variant(
        self,
        _name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
        Ok(TupleVariant(Seq::with_capacity(len), variant))
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        Ok(MapSerializer(
            match len {
                Some(n) => Map::with_capacity(n),
                None => Map::new(),
            },
            None,
        ))
    }

    fn serialize_struct(
        self,
        _name: &'static str,
        len: usize,
    ) -> Result<Self::SerializeStruct, Self::Error> {
        Ok(StructSerializer(Map::with_capacity(len)))
    }

    fn serialize_struct_variant(
        self,
        _name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeStructVariant, Self::Error> {
        Ok(StructVariant(Map::with_capacity(len), variant))
    }
}

struct SeqSerializer<R: Repr>(Seq<R>);
struct TupleVariant<R: Repr>(Seq<R>, &'static str);
struct MapSerializer<R: Repr>(Map<R>, Option<Node<R>>);
struct StructSerializer<R: Repr>(Map<R>);
struct StructVariant<R: Repr>(Map<R>, &'static str);

impl_seq_serializer! {
    impl SerializeSeq for SeqSerializer => serialize_element
    impl SerializeTuple for SeqSerializer => serialize_element
    impl SerializeTupleStruct for SeqSerializer => serialize_field
    impl SerializeTupleVariant for TupleVariant => serialize_field (map)
}

impl_map_serializer! {
    impl SerializeStruct for StructSerializer
    impl SerializeStructVariant for StructVariant (map)
}

impl<R: Repr> SerializeMap for MapSerializer<R> {
    type Ok = Node<R>;
    type Error = SerdeError;

    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
    where
        T: Serialize + ?Sized,
    {
        self.1 = Some(key.serialize(NodeSerializer(PhantomData))?);
        Ok(())
    }

    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: Serialize + ?Sized,
    {
        match self.1.take() {
            Some(k) => self
                .0
                .insert(k, value.serialize(NodeSerializer(PhantomData))?),
            None => unreachable!("serialize_value called before serialize_key"),
        };
        Ok(())
    }

    fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error>
    where
        K: Serialize + ?Sized,
        V: Serialize + ?Sized,
    {
        let k = key.serialize(NodeSerializer(PhantomData))?;
        let v = value.serialize(NodeSerializer(PhantomData))?;
        self.0.insert(k, v);
        Ok(())
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        Ok(self.0.into())
    }
}