parco_xml/dexml/
traits.rs

1use std::borrow::Cow;
2
3use thiserror::Error;
4
5use crate::de::Reader;
6
7/// a trait the allows types to deserialize themselves from xml
8pub trait DeXml<'de>: Sized {
9    /// deserialize from a xml source [`str`], automatically implemented for types once [`DeXml::dexml_reader`] is implemented
10    fn dexml(xml: &'de str) -> Result<Self, DeXmlError> {
11        let mut rdr = Reader::new(xml);
12        Self::dexml_reader(&mut rdr)
13    }
14
15    /// required method for [`DeXml`] trait. the reader provides useful parsing and lexing primitives for deserializing your type
16    fn dexml_reader(reader: &mut Reader<'de>) -> Result<Self, DeXmlError>;
17}
18
19/// a error with a `path` from where in xml document the error happened and the entire xml document for reference
20/// along with a custom message
21#[derive(Debug, Error)]
22#[error("{message} @ `{path}`\n\n{xml}")]
23pub struct DeXmlError {
24    /// the message of what went wrong
25    pub message: Cow<'static, str>,
26    /// where in the xml document
27    pub path: String,
28    /// the xml document
29    pub xml: Box<str>,
30}
31
32impl DeXmlError {
33    pub(crate) fn slice(cursor: usize) -> String {
34        format!("Failed To Slice XML Source @ Byte: `{cursor}`")
35    }
36
37    pub(crate) const EXPECTED_ATTR_NAME: &str = "Expected Attribute Name On Element";
38    pub(crate) const EXPECTED_ATTR_EQUAL: &str = "Expected '=' For Attribute";
39    pub(crate) const EXPECTED_ATTR_VALUE: &str = "Expected A String '...' For Attribute Value";
40    pub(crate) const EXPECTED_ELEMENT: &str = "Expected Element";
41    pub(crate) const EXPECTED_END_OF_ELEMENT: &str = "Expected End Of Element";
42    pub(crate) const EXPECTED_CLOSING_ELEMENT: &str = "Expected Closing Element";
43    pub(crate) const EXPECTED_CHILDREN: &str =
44        "Expected Element To Have Children But It Was A Self Closing Element";
45    pub(crate) const EXPECTED_TEXT: &str = "Expected Text Node";
46}