diff --git a/src/converter.rs b/src/converter.rs index 144df2c..e92e672 100644 --- a/src/converter.rs +++ b/src/converter.rs @@ -4,6 +4,7 @@ use roxmltree::{Node, TextPos}; use thiserror::Error; use crate::types::Module; +use crate::parser::{ParsePrefixedU32, ParsePrefixedU32Error}; #[derive(Debug, Error)] pub enum DomConversionError { @@ -61,34 +62,6 @@ impl DomConversionError { } } -#[derive(Debug, Error)] -pub enum ParsePrefixedU32Error { - #[error("invalid prefix: found {found}")] - InvalidPrefix { found: char }, - #[error("parse int error")] - ParseIntError(#[from] num::ParseIntError), -} - -trait ParsePrefixedU32 { - fn parse_prefixed_u32(&self) -> Result; -} - -impl ParsePrefixedU32 for &str { - fn parse_prefixed_u32(&self) -> Result { - let radix = match self.chars().nth(1) { - Some('x') => 16, - Some(c) if c.is_numeric() => 10, - Some(c) => return Err(ParsePrefixedU32Error::InvalidPrefix { found: c }), - None => return Err(ParsePrefixedU32Error::InvalidPrefix { found: ' ' }), - }; - - match radix { - 10 => Ok(self.parse()?), - radix => Ok(u32::from_str_radix(&self[2..], radix)?), - } - } -} - impl Module { pub fn from_xml_dom(root: Node) -> Result { assert!(root.parent().unwrap().is_root()); diff --git a/src/lib.rs b/src/lib.rs index 63abe1f..8d84cd2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ pub mod types; +pub mod parser; pub mod converter; diff --git a/src/parser.rs b/src/parser.rs new file mode 100644 index 0000000..b5759f2 --- /dev/null +++ b/src/parser.rs @@ -0,0 +1,47 @@ +//! Module for converting XML custom token string to rust types. + +use std::num; + +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum ParsePrefixedU32Error { + #[error("invalid prefix: found {found}")] + InvalidPrefix { found: char }, + #[error("parse int error")] + ParseIntError(#[from] num::ParseIntError), +} + +pub(crate) trait ParsePrefixedU32 { + fn parse_prefixed_u32(&self) -> Result; +} + +impl ParsePrefixedU32 for &str { + fn parse_prefixed_u32(&self) -> Result { + let radix = match self.chars().nth(1) { + Some('x') => 16, + Some(c) if c.is_numeric() => 10, + Some(c) => return Err(ParsePrefixedU32Error::InvalidPrefix { found: c }), + None => return Err(ParsePrefixedU32Error::InvalidPrefix { found: ' ' }), + }; + + match radix { + 10 => Ok(self.parse()?), + radix => Ok(u32::from_str_radix(&self[2..], radix)?), + } + } +} + +#[cfg(test)] +mod test { + use super::ParsePrefixedU32; + + #[test] + fn parse_prefixed_u32() { + assert_eq!("0xdeadbeef".parse_prefixed_u32().unwrap(), 0xdeadbeef); + assert_eq!("0xDEADBEEF".parse_prefixed_u32().unwrap(), 0xdeadbeef); + assert_eq!("1234".parse_prefixed_u32().unwrap(), 1234); + + assert!("0abcde".parse_prefixed_u32().is_err()); + } +}