//! XML is awful. //! //! # Examples //! ``` //! use std::convert::Infallible; //! //! use xml_stinks::deserializer::buffered::Buffered as BufferedDeserializer; //! use xml_stinks::deserializer::{Deserializer, IgnoreEnd}; //! use xml_stinks::tagged::TagStart; //! use xml_stinks::DeserializeTagged; //! //! let mut deserializer = //! BufferedDeserializer::new("BazDF".as_bytes()); //! //! let foo = deserializer.de_tag::("foo", IgnoreEnd::No).unwrap(); //! //! assert_eq!(&foo.name, "Baz"); //! assert_eq!(foo.bar.num, 223); //! //! struct Foo //! { //! name: String, //! bar: Bar, //! } //! //! impl DeserializeTagged for Foo //! { //! type Error = Infallible; //! //! fn deserialize( //! start: &TagStart, //! deserializer: &mut TDeserializer, //! ) -> Result //! { //! let name = deserializer.de_text().unwrap(); //! //! let bar = deserializer.de_tag::("bar", IgnoreEnd::No).unwrap(); //! //! Ok(Self { name, bar }) //! } //! } //! //! struct Bar //! { //! num: u32, //! } //! //! impl DeserializeTagged for Bar //! { //! type Error = Infallible; //! //! fn deserialize( //! start: &TagStart, //! deserializer: &mut TDeserializer, //! ) -> Result //! { //! let num = u32::from_str_radix(&deserializer.de_text().unwrap(), 16).unwrap(); //! //! Ok(Self { num }) //! } //! } //! ``` #![deny(clippy::all, clippy::pedantic, unsafe_code, missing_docs)] use crate::deserializer::{Deserializer, Error as DeserializerError, MaybeStatic}; use crate::tagged::TagStart; pub mod attribute; pub mod deserializer; pub mod escape; pub mod tagged; mod event; mod util; /// Trait implemented by types that want to be deserializable from tagged XML elements. pub trait DeserializeTagged: Sized + MaybeStatic { /// Error type. type Error: std::error::Error + Send + Sync + 'static; /// Deserializes into a new `Self`. /// /// # Errors /// When or if a error is returned is decided by the type implementing this trait. fn deserialize( start: &TagStart, deserializer: &mut TDeserializer, ) -> Result; } /// Result extension. pub trait ResultExt { /// Returns `Ok(None)` if `Err` is `DeserializerError::UnexpectedEvent`. /// /// # Errors /// Returns `Err` if a `Deserializer` error occurs. fn try_event(self) -> Result, DeserializerError>; } impl ResultExt for Result> { fn try_event(self) -> Result, DeserializerError> { self.map_or_else( |err| { if let DeserializerError::UnexpectedEvent { expected_event_name: _, found_event: _, } = err { return Ok(None); } Err(err) }, |value| Ok(Some(value)), ) } }