diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 70 |
1 files changed, 26 insertions, 44 deletions
@@ -24,20 +24,24 @@ use std::fs::File; use std::io::Read; +use quick_xml::events::BytesStart; + use crate::command::{Command, Error as CommandError}; -use crate::xml::element::{Element, Elements, FromElements}; -use crate::xml::parser::{Error as ParserError, Parser}; +use crate::deserialization::buffer_deserializer::BufferDeserializer; +use crate::deserialization::{Deserialize, Deserializer, DeserializerError, IgnoreEnd}; pub mod command; -mod xml; +mod deserialization; +/// XML. #[cfg(feature = "include-xml")] const GL_REGISTRY_XML: &[u8] = include_bytes!("../OpenGL-Registry/xml/gl.xml"); const REGISTRY_TAG_NAME: &str = "registry"; /// Representation of the OpenGL registry. +#[derive(Debug, PartialEq, Eq)] pub struct Registry { commands: Vec<Command>, @@ -62,15 +66,12 @@ impl Registry /// Returns `Err` if parsing fails in any way. pub fn retrieve_from_bytes(xml_bytes: &[u8]) -> Result<Registry, RegistryError> { - let mut parser = Parser::new(xml_bytes); - - let elements = parser.parse().map_err(ParsingError)?; + let mut deserializer = BufferDeserializer::new(xml_bytes); - let registry_element = elements - .get_first_tagged_element(REGISTRY_TAG_NAME) - .ok_or(RegistryError::MissingRegistryElement)?; + deserializer.skip_to_tag_start(REGISTRY_TAG_NAME)?; - let registry = Registry::from_elements(registry_element.child_elements())?; + let registry = + deserializer.de_tag::<Registry>(REGISTRY_TAG_NAME, IgnoreEnd::Yes)?; Ok(registry) } @@ -110,35 +111,21 @@ impl Registry } } -impl FromElements for Registry +impl Deserialize for Registry { type Error = RegistryError; - fn from_elements(elements: &Elements) -> Result<Self, Self::Error> + fn deserialize<TDeserializer: Deserializer>( + _start: &BytesStart, + deserializer: &mut TDeserializer, + ) -> Result<Self, Self::Error> { - let commands_element = elements - .get_first_tagged_element("commands") - .ok_or(Self::Error::MissingCommandsElement)?; - - let command_elements = - commands_element - .child_elements() - .into_iter() - .filter_map(|element| match element { - Element::Tagged(tagged_element) - if tagged_element.name() == "command" => - { - Some(tagged_element) - } - _ => None, - }); - - let commands = command_elements - .into_iter() - .map(|command_element| { - Command::from_elements(command_element.child_elements()) - }) - .collect::<Result<Vec<_>, _>>()?; + deserializer.skip_to_tag_start("commands")?; + + let commands = + deserializer.de_tag_with("commands", IgnoreEnd::No, |_, deserializer| { + deserializer.de_tag_list::<Command>("command") + })?; Ok(Self { commands }) } @@ -160,16 +147,11 @@ pub enum RegistryError #[error("Invalid command")] InvalidCommand(#[from] CommandError), - /// Parsing failed. - #[error("Parsing failed")] - ParsingFailed(#[from] ParsingError), - /// I/O failed. #[error("I/O failed")] IOFailed(#[from] std::io::Error), -} -/// Parsing error. -#[derive(Debug, thiserror::Error)] -#[error(transparent)] -pub struct ParsingError(#[from] ParserError); + /// Deserialization failed. + #[error("Deserialization failed")] + DeserializationFailed(#[from] DeserializerError), +} |