// this module is based on the content module in serde::private::ser
use serde::ser::{self, Serialize, Serializer};
use std::cmp::Ordering;
use std::marker::PhantomData;

/// Represents variable typed content.
///
/// This is used for the serialization system to represent values
/// before the actual snapshots are written and is also exposed to
/// dynamic redaction functions.
///
/// Some enum variants are intentionally not exposed to user code.
/// It's generally recommended to construct content objects by
/// using the [`From`](std::convert::From) trait and by using the
/// accessor methods to assert on it.
///
/// While matching on the content is possible in theory it is
/// recommended against.  The reason for this is that the content
/// enum holds variants that can "wrap" values where it's not
/// expected.  For instance if a field holds an `Option<String>`
/// you cannot use pattern matching to extract the string as it
/// will be contained in an internal `Some` variant that is not
/// exposed.  On the other hand the `as_str` method will
/// automatically resolve such internal wrappers.
///
/// If you do need to pattern match you should use the
/// `resolve_inner` method to resolve such internal wrappers.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Content {
    Bool(bool),

    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),
    U128(u128),

    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),
    I128(i128),

    F32(f32),
    F64(f64),

    Char(char),
    String(String),
    Bytes(Vec<u8>),

    #[doc(hidden)]
    None,
    #[doc(hidden)]
    Some(Box<Content>),

    #[doc(hidden)]
    Unit,
    #[doc(hidden)]
    UnitStruct(&'static str),
    #[doc(hidden)]
    UnitVariant(&'static str, u32, &'static str),
    #[doc(hidden)]
    NewtypeStruct(&'static str, Box<Content>),
    #[doc(hidden)]
    NewtypeVariant(&'static str, u32, &'static str, Box<Content>),

    Seq(Vec<Content>),
    #[doc(hidden)]
    Tuple(Vec<Content>),
    #[doc(hidden)]
    TupleStruct(&'static str, Vec<Content>),
    #[doc(hidden)]
    TupleVariant(&'static str, u32, &'static str, Vec<Content>),
    Map(Vec<(Content, Content)>),
    #[doc(hidden)]
    Struct(&'static str, Vec<(&'static str, Content)>),
    #[doc(hidden)]
    StructVariant(
        &'static str,
        u32,
        &'static str,
        Vec<(&'static str, Content)>,
    ),
}

#[derive(PartialEq, PartialOrd, Debug)]
pub enum Key<'a> {
    Bool(bool),
    U64(u64),
    I64(i64),
    F64(f64),
    U128(u128),
    I128(i128),
    Str(&'a str),
    Bytes(&'a [u8]),
    Other,
}

impl<'a> Eq for Key<'a> {}

impl<'a> Ord for Key<'a> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).unwrap_or(Ordering::Less)
    }
}

macro_rules! impl_from {
    ($ty:ty, $newty:ident) => {
        impl From<$ty> for Content {
            fn from(value: $ty) -> Content {
                Content::$newty(value)
            }
        }
    };
}

impl_from!(bool, Bool);
impl_from!(u8, U8);
impl_from!(u16, U16);
impl_from!(u32, U32);
impl_from!(u64, U64);
impl_from!(u128, U128);
impl_from!(i8, I8);
impl_from!(i16, I16);
impl_from!(i32, I32);
impl_from!(i64, I64);
impl_from!(i128, I128);
impl_from!(f32, F32);
impl_from!(f64, F64);
impl_from!(char, Char);
impl_from!(String, String);
impl_from!(Vec<u8>, Bytes);

impl From<()> for Content {
    fn from(_value: ()) -> Content {
        Content::Unit
    }
}

impl<'a> From<&'a str> for Content {
    fn from(value: &'a str) -> Content {
        Content::String(value.to_string())
    }
}

impl<'a> From<&'a [u8]> for Content {
    fn from(value: &'a [u8]) -> Content {
        Content::Bytes(value.to_vec())
    }
}

impl Content {
    /// This resolves the innermost content in a chain of
    /// wrapped content.
    ///
    /// For instance if you encounter an `Option<Option<String>>`
    /// field the content will be wrapped twice in an internal
    /// option wrapper.  If you need to pattern match you will
    /// need in some situations to first resolve the inner value
    /// before such matching can take place as there is no exposed
    /// way to match on these wrappers.
    ///
    /// This method does not need to be called for the `as_`
    /// methods which resolve automatically.
    pub fn resolve_inner(&self) -> &Content {
        match *self {
            Content::Some(ref v)
            | Content::NewtypeStruct(_, ref v)
            | Content::NewtypeVariant(_, _, _, ref v) => v.resolve_inner(),
            ref other => other,
        }
    }

    /// Mutable version of [`resolve_inner`](Self::resolve_inner).
    pub fn resolve_inner_mut(&mut self) -> &mut Content {
        match *self {
            Content::Some(ref mut v)
            | Content::NewtypeStruct(_, ref mut v)
            | Content::NewtypeVariant(_, _, _, ref mut v) => v.resolve_inner_mut(),
            ref mut other => other,
        }
    }

    /// Returns the value as string
    pub fn as_str(&self) -> Option<&str> {
        match self.resolve_inner() {
            Content::String(ref s) => Some(s.as_str()),
            _ => None,
        }
    }

    /// Returns the value as bytes
    pub fn as_bytes(&self) -> Option<&[u8]> {
        match self.resolve_inner() {
            Content::Bytes(ref b) => Some(&*b),
            _ => None,
        }
    }

    /// Returns the value as slice of content values.
    pub fn as_slice(&self) -> Option<&[Content]> {
        match self.resolve_inner() {
            Content::Seq(ref v) | Content::Tuple(ref v) | Content::TupleVariant(_, _, _, ref v) => {
                Some(&v[..])
            }
            _ => None,
        }
    }

    /// Returns true if the value is nil.
    pub fn is_nil(&self) -> bool {
        if let Content::None | Content::Unit = self.resolve_inner() {
            true
        } else {
            false
        }
    }

    pub(crate) fn as_key(&self) -> Key<'_> {
        match *self.resolve_inner() {
            Content::Bool(val) => Key::Bool(val),
            Content::Char(val) => Key::U64(val as u64),
            Content::U16(val) => Key::U64(val.into()),
            Content::U32(val) => Key::U64(val.into()),
            Content::U64(val) => Key::U64(val),
            Content::U128(val) => Key::U128(val),
            Content::I16(val) => Key::I64(val.into()),
            Content::I32(val) => Key::I64(val.into()),
            Content::I64(val) => Key::I64(val),
            Content::I128(val) => Key::I128(val),
            Content::F32(val) => Key::F64(val.into()),
            Content::F64(val) => Key::F64(val),
            Content::String(ref val) => Key::Str(val.as_str()),
            Content::Bytes(ref val) => Key::Bytes(&val[..]),
            _ => Key::Other,
        }
    }

    /// Returns the value as bool
    pub fn as_bool(&self) -> Option<bool> {
        match *self.resolve_inner() {
            Content::Bool(val) => Some(val),
            _ => None,
        }
    }

    /// Returns the value as u64
    pub fn as_u64(&self) -> Option<u64> {
        match *self.resolve_inner() {
            Content::U8(v) => Some(u64::from(v)),
            Content::U16(v) => Some(u64::from(v)),
            Content::U32(v) => Some(u64::from(v)),
            Content::U64(v) => Some(v),
            Content::U128(v) => {
                let rv = v as u64;
                if rv as u128 == v {
                    Some(rv)
                } else {
                    None
                }
            }
            Content::I8(v) if v >= 0 => Some(v as u64),
            Content::I16(v) if v >= 0 => Some(v as u64),
            Content::I32(v) if v >= 0 => Some(v as u64),
            Content::I64(v) if v >= 0 => Some(v as u64),
            Content::I128(v) => {
                let rv = v as u64;
                if rv as i128 == v {
                    Some(rv)
                } else {
                    None
                }
            }
            _ => None,
        }
    }

    /// Returns the value as u128
    pub fn as_u128(&self) -> Option<u128> {
        match *self.resolve_inner() {
            Content::U128(v) => Some(v),
            Content::I128(v) if v >= 0 => Some(v as u128),
            _ => self.as_u64().map(u128::from),
        }
    }

    /// Returns the value as i64
    pub fn as_i64(&self) -> Option<i64> {
        match *self.resolve_inner() {
            Content::U8(v) => Some(i64::from(v)),
            Content::U16(v) => Some(i64::from(v)),
            Content::U32(v) => Some(i64::from(v)),
            Content::U64(v) => {
                let rv = v as i64;
                if rv as u64 == v {
                    Some(rv)
                } else {
                    None
                }
            }
            Content::U128(v) => {
                let rv = v as i64;
                if rv as u128 == v {
                    Some(rv)
                } else {
                    None
                }
            }
            Content::I8(v) => Some(i64::from(v)),
            Content::I16(v) => Some(i64::from(v)),
            Content::I32(v) => Some(i64::from(v)),
            Content::I64(v) => Some(v),
            Content::I128(v) => {
                let rv = v as i64;
                if rv as i128 == v {
                    Some(rv)
                } else {
                    None
                }
            }
            _ => None,
        }
    }

    /// Returns the value as i128
    pub fn as_i128(&self) -> Option<i128> {
        match *self.resolve_inner() {
            Content::U128(v) => {
                let rv = v as i128;
                if rv as u128 == v {
                    Some(rv)
                } else {
                    None
                }
            }
            Content::I128(v) => Some(v),
            _ => self.as_i64().map(i128::from),
        }
    }

    /// Returns the value as f64
    pub fn as_f64(&self) -> Option<f64> {
        match *self.resolve_inner() {
            Content::F32(v) => Some(f64::from(v)),
            Content::F64(v) => Some(v),
            _ => None,
        }
    }

    pub(crate) fn sort_maps(&mut self) {
        self.walk(&mut |content| {
            if let Content::Map(ref mut items) = content {
                items.sort_by(|a, b| a.0.as_key().cmp(&b.0.as_key()));
            }
            true
        })
    }

    /// Recursively walks the content structure mutably.
    ///
    /// The callback is invoked for every content in the tree.
    pub fn walk<F: FnMut(&mut Content) -> bool>(&mut self, visit: &mut F) {
        if !visit(self) {
            return;
        }

        match *self {
            Content::Some(ref mut inner) => {
                Self::walk(&mut *inner, visit);
            }
            Content::NewtypeStruct(_, ref mut inner) => {
                Self::walk(&mut *inner, visit);
            }
            Content::NewtypeVariant(_, _, _, ref mut inner) => {
                Self::walk(&mut *inner, visit);
            }
            Content::Seq(ref mut vec) => {
                for inner in vec.iter_mut() {
                    Self::walk(inner, visit);
                }
            }
            Content::Map(ref mut vec) => {
                for inner in vec.iter_mut() {
                    Self::walk(&mut inner.0, visit);
                    Self::walk(&mut inner.1, visit);
                }
            }
            Content::Struct(_, ref mut vec) => {
                for inner in vec.iter_mut() {
                    Self::walk(&mut inner.1, visit);
                }
            }
            Content::StructVariant(_, _, _, ref mut vec) => {
                for inner in vec.iter_mut() {
                    Self::walk(&mut inner.1, visit);
                }
            }
            Content::Tuple(ref mut vec) => {
                for inner in vec.iter_mut() {
                    Self::walk(inner, visit);
                }
            }
            Content::TupleStruct(_, ref mut vec) => {
                for inner in vec.iter_mut() {
                    Self::walk(inner, visit);
                }
            }
            Content::TupleVariant(_, _, _, ref mut vec) => {
                for inner in vec.iter_mut() {
                    Self::walk(inner, visit);
                }
            }
            _ => {}
        }
    }
}

impl Serialize for Content {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match *self {
            Content::Bool(b) => serializer.serialize_bool(b),
            Content::U8(u) => serializer.serialize_u8(u),
            Content::U16(u) => serializer.serialize_u16(u),
            Content::U32(u) => serializer.serialize_u32(u),
            Content::U64(u) => serializer.serialize_u64(u),
            Content::U128(u) => serializer.serialize_u128(u),
            Content::I8(i) => serializer.serialize_i8(i),
            Content::I16(i) => serializer.serialize_i16(i),
            Content::I32(i) => serializer.serialize_i32(i),
            Content::I64(i) => serializer.serialize_i64(i),
            Content::I128(i) => serializer.serialize_i128(i),
            Content::F32(f) => serializer.serialize_f32(f),
            Content::F64(f) => serializer.serialize_f64(f),
            Content::Char(c) => serializer.serialize_char(c),
            Content::String(ref s) => serializer.serialize_str(s),
            Content::Bytes(ref b) => serializer.serialize_bytes(b),
            Content::None => serializer.serialize_none(),
            Content::Some(ref c) => serializer.serialize_some(&**c),
            Content::Unit => serializer.serialize_unit(),
            Content::UnitStruct(n) => serializer.serialize_unit_struct(n),
            Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v),
            Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c),
            Content::NewtypeVariant(n, i, v, ref c) => {
                serializer.serialize_newtype_variant(n, i, v, &**c)
            }
            Content::Seq(ref elements) => elements.serialize(serializer),
            Content::Tuple(ref elements) => {
                use serde::ser::SerializeTuple;
                let mut tuple = serializer.serialize_tuple(elements.len())?;
                for e in elements {
                    tuple.serialize_element(e)?;
                }
                tuple.end()
            }
            Content::TupleStruct(n, ref fields) => {
                use serde::ser::SerializeTupleStruct;
                let mut ts = serializer.serialize_tuple_struct(n, fields.len())?;
                for f in fields {
                    ts.serialize_field(f)?;
                }
                ts.end()
            }
            Content::TupleVariant(n, i, v, ref fields) => {
                use serde::ser::SerializeTupleVariant;
                let mut tv = serializer.serialize_tuple_variant(n, i, v, fields.len())?;
                for f in fields {
                    tv.serialize_field(f)?;
                }
                tv.end()
            }
            Content::Map(ref entries) => {
                use serde::ser::SerializeMap;
                let mut map = serializer.serialize_map(Some(entries.len()))?;
                for &(ref k, ref v) in entries {
                    map.serialize_entry(k, v)?;
                }
                map.end()
            }
            Content::Struct(n, ref fields) => {
                use serde::ser::SerializeStruct;
                let mut s = serializer.serialize_struct(n, fields.len())?;
                for &(k, ref v) in fields {
                    s.serialize_field(k, v)?;
                }
                s.end()
            }
            Content::StructVariant(n, i, v, ref fields) => {
                use serde::ser::SerializeStructVariant;
                let mut sv = serializer.serialize_struct_variant(n, i, v, fields.len())?;
                for &(k, ref v) in fields {
                    sv.serialize_field(k, v)?;
                }
                sv.end()
            }
        }
    }
}

pub struct ContentSerializer<E> {
    error: PhantomData<E>,
}

impl<E> ContentSerializer<E> {
    pub fn new() -> Self {
        ContentSerializer { error: PhantomData }
    }
}

impl<E> Serializer for ContentSerializer<E>
where
    E: ser::Error,
{
    type Ok = Content;
    type Error = E;

    type SerializeSeq = SerializeSeq<E>;
    type SerializeTuple = SerializeTuple<E>;
    type SerializeTupleStruct = SerializeTupleStruct<E>;
    type SerializeTupleVariant = SerializeTupleVariant<E>;
    type SerializeMap = SerializeMap<E>;
    type SerializeStruct = SerializeStruct<E>;
    type SerializeStructVariant = SerializeStructVariant<E>;

    fn serialize_bool(self, v: bool) -> Result<Content, E> {
        Ok(Content::Bool(v))
    }

    fn serialize_i8(self, v: i8) -> Result<Content, E> {
        Ok(Content::I8(v))
    }

    fn serialize_i16(self, v: i16) -> Result<Content, E> {
        Ok(Content::I16(v))
    }

    fn serialize_i32(self, v: i32) -> Result<Content, E> {
        Ok(Content::I32(v))
    }

    fn serialize_i64(self, v: i64) -> Result<Content, E> {
        Ok(Content::I64(v))
    }

    fn serialize_i128(self, v: i128) -> Result<Content, E> {
        Ok(Content::I128(v))
    }

    fn serialize_u8(self, v: u8) -> Result<Content, E> {
        Ok(Content::U8(v))
    }

    fn serialize_u16(self, v: u16) -> Result<Content, E> {
        Ok(Content::U16(v))
    }

    fn serialize_u32(self, v: u32) -> Result<Content, E> {
        Ok(Content::U32(v))
    }

    fn serialize_u64(self, v: u64) -> Result<Content, E> {
        Ok(Content::U64(v))
    }

    fn serialize_u128(self, v: u128) -> Result<Content, E> {
        Ok(Content::U128(v))
    }

    fn serialize_f32(self, v: f32) -> Result<Content, E> {
        Ok(Content::F32(v))
    }

    fn serialize_f64(self, v: f64) -> Result<Content, E> {
        Ok(Content::F64(v))
    }

    fn serialize_char(self, v: char) -> Result<Content, E> {
        Ok(Content::Char(v))
    }

    fn serialize_str(self, value: &str) -> Result<Content, E> {
        Ok(Content::String(value.to_owned()))
    }

    fn serialize_bytes(self, value: &[u8]) -> Result<Content, E> {
        Ok(Content::Bytes(value.to_owned()))
    }

    fn serialize_none(self) -> Result<Content, E> {
        Ok(Content::None)
    }

    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Content, E>
    where
        T: Serialize,
    {
        Ok(Content::Some(Box::new(value.serialize(self)?)))
    }

    fn serialize_unit(self) -> Result<Content, E> {
        Ok(Content::Unit)
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<Content, E> {
        Ok(Content::UnitStruct(name))
    }

    fn serialize_unit_variant(
        self,
        name: &'static str,
        variant_index: u32,
        variant: &'static str,
    ) -> Result<Content, E> {
        Ok(Content::UnitVariant(name, variant_index, variant))
    }

    fn serialize_newtype_struct<T: ?Sized>(
        self,
        name: &'static str,
        value: &T,
    ) -> Result<Content, E>
    where
        T: Serialize,
    {
        Ok(Content::NewtypeStruct(
            name,
            Box::new(value.serialize(self)?),
        ))
    }

    fn serialize_newtype_variant<T: ?Sized>(
        self,
        name: &'static str,
        variant_index: u32,
        variant: &'static str,
        value: &T,
    ) -> Result<Content, E>
    where
        T: Serialize,
    {
        Ok(Content::NewtypeVariant(
            name,
            variant_index,
            variant,
            Box::new(value.serialize(self)?),
        ))
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, E> {
        Ok(SerializeSeq {
            elements: Vec::with_capacity(len.unwrap_or(0)),
            error: PhantomData,
        })
    }

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, E> {
        Ok(SerializeTuple {
            elements: Vec::with_capacity(len),
            error: PhantomData,
        })
    }

    fn serialize_tuple_struct(
        self,
        name: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleStruct, E> {
        Ok(SerializeTupleStruct {
            name,
            fields: Vec::with_capacity(len),
            error: PhantomData,
        })
    }

    fn serialize_tuple_variant(
        self,
        name: &'static str,
        variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleVariant, E> {
        Ok(SerializeTupleVariant {
            name,
            variant_index,
            variant,
            fields: Vec::with_capacity(len),
            error: PhantomData,
        })
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, E> {
        Ok(SerializeMap {
            entries: Vec::with_capacity(len.unwrap_or(0)),
            key: None,
            error: PhantomData,
        })
    }

    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, E> {
        Ok(SerializeStruct {
            name,
            fields: Vec::with_capacity(len),
            error: PhantomData,
        })
    }

    fn serialize_struct_variant(
        self,
        name: &'static str,
        variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeStructVariant, E> {
        Ok(SerializeStructVariant {
            name,
            variant_index,
            variant,
            fields: Vec::with_capacity(len),
            error: PhantomData,
        })
    }
}

pub struct SerializeSeq<E> {
    elements: Vec<Content>,
    error: PhantomData<E>,
}

impl<E> ser::SerializeSeq for SerializeSeq<E>
where
    E: ser::Error,
{
    type Ok = Content;
    type Error = E;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
    where
        T: Serialize,
    {
        let value = value.serialize(ContentSerializer::<E>::new())?;
        self.elements.push(value);
        Ok(())
    }

    fn end(self) -> Result<Content, E> {
        Ok(Content::Seq(self.elements))
    }
}

pub struct SerializeTuple<E> {
    elements: Vec<Content>,
    error: PhantomData<E>,
}

impl<E> ser::SerializeTuple for SerializeTuple<E>
where
    E: ser::Error,
{
    type Ok = Content;
    type Error = E;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
    where
        T: Serialize,
    {
        let value = value.serialize(ContentSerializer::<E>::new())?;
        self.elements.push(value);
        Ok(())
    }

    fn end(self) -> Result<Content, E> {
        Ok(Content::Tuple(self.elements))
    }
}

pub struct SerializeTupleStruct<E> {
    name: &'static str,
    fields: Vec<Content>,
    error: PhantomData<E>,
}

impl<E> ser::SerializeTupleStruct for SerializeTupleStruct<E>
where
    E: ser::Error,
{
    type Ok = Content;
    type Error = E;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
    where
        T: Serialize,
    {
        let value = value.serialize(ContentSerializer::<E>::new())?;
        self.fields.push(value);
        Ok(())
    }

    fn end(self) -> Result<Content, E> {
        Ok(Content::TupleStruct(self.name, self.fields))
    }
}

pub struct SerializeTupleVariant<E> {
    name: &'static str,
    variant_index: u32,
    variant: &'static str,
    fields: Vec<Content>,
    error: PhantomData<E>,
}

impl<E> ser::SerializeTupleVariant for SerializeTupleVariant<E>
where
    E: ser::Error,
{
    type Ok = Content;
    type Error = E;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
    where
        T: Serialize,
    {
        let value = value.serialize(ContentSerializer::<E>::new())?;
        self.fields.push(value);
        Ok(())
    }

    fn end(self) -> Result<Content, E> {
        Ok(Content::TupleVariant(
            self.name,
            self.variant_index,
            self.variant,
            self.fields,
        ))
    }
}

pub struct SerializeMap<E> {
    entries: Vec<(Content, Content)>,
    key: Option<Content>,
    error: PhantomData<E>,
}

impl<E> ser::SerializeMap for SerializeMap<E>
where
    E: ser::Error,
{
    type Ok = Content;
    type Error = E;

    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), E>
    where
        T: Serialize,
    {
        let key = key.serialize(ContentSerializer::<E>::new())?;
        self.key = Some(key);
        Ok(())
    }

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
    where
        T: Serialize,
    {
        let key = self
            .key
            .take()
            .expect("serialize_value called before serialize_key");
        let value = value.serialize(ContentSerializer::<E>::new())?;
        self.entries.push((key, value));
        Ok(())
    }

    fn end(self) -> Result<Content, E> {
        Ok(Content::Map(self.entries))
    }

    fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<(), E>
    where
        K: Serialize,
        V: Serialize,
    {
        let key = key.serialize(ContentSerializer::<E>::new())?;
        let value = value.serialize(ContentSerializer::<E>::new())?;
        self.entries.push((key, value));
        Ok(())
    }
}

pub struct SerializeStruct<E> {
    name: &'static str,
    fields: Vec<(&'static str, Content)>,
    error: PhantomData<E>,
}

impl<E> ser::SerializeStruct for SerializeStruct<E>
where
    E: ser::Error,
{
    type Ok = Content;
    type Error = E;

    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), E>
    where
        T: Serialize,
    {
        let value = value.serialize(ContentSerializer::<E>::new())?;
        self.fields.push((key, value));
        Ok(())
    }

    fn end(self) -> Result<Content, E> {
        Ok(Content::Struct(self.name, self.fields))
    }
}

pub struct SerializeStructVariant<E> {
    name: &'static str,
    variant_index: u32,
    variant: &'static str,
    fields: Vec<(&'static str, Content)>,
    error: PhantomData<E>,
}

impl<E> ser::SerializeStructVariant for SerializeStructVariant<E>
where
    E: ser::Error,
{
    type Ok = Content;
    type Error = E;

    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), E>
    where
        T: Serialize,
    {
        let value = value.serialize(ContentSerializer::<E>::new())?;
        self.fields.push((key, value));
        Ok(())
    }

    fn end(self) -> Result<Content, E> {
        Ok(Content::StructVariant(
            self.name,
            self.variant_index,
            self.variant,
            self.fields,
        ))
    }
}
