serde-xml-rs 0.8.2

xml-rs based deserializer for Serde (compatible with 1.0)
Documentation
use super::{
    child::ChildSerializer,
    plain::PlainTextSerializer,
    writer::{Attribute, Writer},
};
use crate::{
    config::{CONTENT, TEXT},
    error::{Error, Result},
};
use std::io::Write;

pub struct StructSerializer<'a, W> {
    writer: &'a mut Writer<W>,
    name: String,
    parent_name: Option<String>,
    attributes: Vec<Attribute>,
    parent_element_written: bool,
    start_element_written: bool,
}

impl<'a, W> StructSerializer<'a, W> {
    pub fn new(writer: &'a mut Writer<W>, name: String) -> Self {
        Self {
            writer,
            name,
            parent_name: None,
            attributes: Vec::new(),
            parent_element_written: false,
            start_element_written: false,
        }
    }

    pub fn new_variant(
        writer: &'a mut Writer<W>,
        parent_name: Option<String>,
        name: String,
    ) -> Self {
        Self {
            writer,
            name,
            parent_name,
            attributes: Vec::new(),
            parent_element_written: false,
            start_element_written: false,
        }
    }
}

impl<W: Write> StructSerializer<'_, W> {
    fn ensure_parent_element_written(&mut self) -> Result<()> {
        if let Some(parent_name) = &self.parent_name {
            if !self.parent_element_written {
                self.writer.start_element(parent_name)?;
                self.parent_element_written = true;
            }
        }
        Ok(())
    }

    fn ensure_start_element_written(&mut self) -> Result<()> {
        if !self.start_element_written {
            self.writer
                .start_element_with_attributes(&self.name, &self.attributes)?;
            self.start_element_written = true;
        }
        Ok(())
    }
}

impl<W: Write> serde::ser::SerializeStruct for StructSerializer<'_, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
    where
        T: ?Sized + serde::Serialize,
    {
        self.ensure_parent_element_written()?;
        if let Some(name) = key.strip_prefix("@") {
            if self.start_element_written {
                Err(Error::AttributesMustComeBeforeElements {
                    element_name: self.name.to_string(),
                    attribute_name: key,
                })
            } else {
                if let Some(value) = value.serialize(PlainTextSerializer)? {
                    self.attributes.push(Attribute { name, value });
                }
                Ok(())
            }
        } else {
            self.ensure_start_element_written()?;
            if key == TEXT {
                if let Some(value) = value.serialize(PlainTextSerializer)? {
                    self.writer.characters(value)?;
                }
            } else if key == CONTENT {
                value.serialize(ChildSerializer::new(self.writer, None))?;
            } else {
                value.serialize(ChildSerializer::new(self.writer, Some(key.to_string())))?;
            }
            Ok(())
        }
    }

    fn end(mut self) -> Result<Self::Ok> {
        self.ensure_parent_element_written()?;
        self.ensure_start_element_written()?;
        self.writer.end_element()?;
        if self.parent_name.is_some() {
            self.writer.end_element()?;
        }
        Ok(())
    }
}

impl<W: Write> serde::ser::SerializeStructVariant for StructSerializer<'_, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
    where
        T: ?Sized + serde::Serialize,
    {
        <StructSerializer<W> as serde::ser::SerializeStruct>::serialize_field(self, key, value)
    }

    fn end(self) -> Result<Self::Ok> {
        <StructSerializer<W> as serde::ser::SerializeStruct>::end(self)
    }
}

pub struct MapSerializer<'a, W> {
    writer: &'a mut Writer<W>,
    element_name: String,
    should_end_element: bool,
}

impl<'a, W> MapSerializer<'a, W> {
    pub fn new(writer: &'a mut Writer<W>, should_end_element: bool) -> Self {
        Self {
            writer,
            element_name: "".to_string(),
            should_end_element,
        }
    }
}

impl<W: Write> serde::ser::SerializeMap for MapSerializer<'_, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
    where
        T: ?Sized + serde::Serialize,
    {
        self.element_name = key
            .serialize(PlainTextSerializer)?
            .ok_or(Error::Unexpected {
                expected: "key",
                but_got: "Option::None".to_string(),
            })?;
        Ok(())
    }

    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
    where
        T: ?Sized + serde::Serialize,
    {
        let element_name = std::mem::replace(&mut self.element_name, "".to_string());
        if element_name == TEXT {
            if let Some(text) = value.serialize(PlainTextSerializer)? {
                self.writer.characters(text)?;
            }
        } else {
            value.serialize(ChildSerializer::new(self.writer, Some(element_name)))?;
        }
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        if self.should_end_element {
            self.writer.end_element()?;
        }
        Ok(())
    }
}