use quick_xml::events::{BytesEnd, BytesStart};
use quick_xml::{Reader, Writer};
use std::io::{BufRead, Write};
mod raw_xml;
pub mod serde_helpers;
pub use raw_xml::{PositionedAttr, PositionedNode, RawXmlElement, RawXmlNode, RawXmlStreamReader};
pub use serde_helpers::{ooxml_bool, ooxml_bool_required};
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("XML error: {0}")]
Xml(#[from] quick_xml::Error),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("invalid XML: {0}")]
Invalid(String),
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
pub enum ParseError {
#[error("XML error: {0}")]
Xml(#[from] quick_xml::Error),
#[error("raw XML error: {0}")]
RawXml(#[from] Error),
#[error("unexpected element: {0}")]
UnexpectedElement(String),
#[error("missing attribute: {0}")]
MissingAttribute(String),
#[error("invalid value: {0}")]
InvalidValue(String),
}
#[derive(Debug, thiserror::Error)]
pub enum SerializeError {
#[error("XML error: {0}")]
Xml(#[from] quick_xml::Error),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("raw XML error: {0}")]
RawXml(#[from] Error),
}
pub trait FromXml: Sized {
fn from_xml<R: BufRead>(
reader: &mut Reader<R>,
start_tag: &BytesStart,
is_empty: bool,
) -> std::result::Result<Self, ParseError>;
}
pub trait ToXml {
fn write_attrs<'a>(&self, start: BytesStart<'a>) -> BytesStart<'a> {
start
}
fn write_children<W: Write>(
&self,
_writer: &mut Writer<W>,
) -> std::result::Result<(), SerializeError> {
Ok(())
}
fn is_empty_element(&self) -> bool {
false
}
fn write_element<W: Write>(
&self,
tag: &str,
writer: &mut Writer<W>,
) -> std::result::Result<(), SerializeError> {
use quick_xml::events::Event;
let start = BytesStart::new(tag);
let start = self.write_attrs(start);
if self.is_empty_element() {
writer.write_event(Event::Empty(start))?;
} else {
writer.write_event(Event::Start(start))?;
self.write_children(writer)?;
writer.write_event(Event::End(BytesEnd::new(tag)))?;
}
Ok(())
}
}
impl<T: ToXml> ToXml for Box<T> {
fn write_attrs<'a>(&self, start: BytesStart<'a>) -> BytesStart<'a> {
(**self).write_attrs(start)
}
fn write_children<W: Write>(
&self,
writer: &mut Writer<W>,
) -> std::result::Result<(), SerializeError> {
(**self).write_children(writer)
}
fn is_empty_element(&self) -> bool {
(**self).is_empty_element()
}
fn write_element<W: Write>(
&self,
tag: &str,
writer: &mut Writer<W>,
) -> std::result::Result<(), SerializeError> {
(**self).write_element(tag, writer)
}
}