From 8188b4fef8007a97d5d46b8225d72a59d9619137 Mon Sep 17 00:00:00 2001 From: Wataru Otsubo Date: Thu, 30 Jan 2025 01:18:31 +0900 Subject: [PATCH] new: Module.amod parsing --- src/converter.rs | 30 ++++++++++++++++++++++-- src/parser.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ src/types.rs | 2 +- 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/converter.rs b/src/converter.rs index e92e672..a2e808d 100644 --- a/src/converter.rs +++ b/src/converter.rs @@ -1,10 +1,12 @@ +//! Convert DOM to register interface, complementing optional parameters. + use std::num; use roxmltree::{Node, TextPos}; use thiserror::Error; +use crate::parser::{ParseEnumError, ParsePrefixedU32, ParsePrefixedU32Error}; use crate::types::Module; -use crate::parser::{ParsePrefixedU32, ParsePrefixedU32Error}; #[derive(Debug, Error)] pub enum DomConversionError { @@ -27,6 +29,13 @@ pub enum DomConversionError { #[source] source: ParsePrefixedU32Error, }, + #[error("string conversion error: {start} - {end}", start = pos.0, end = pos.1)] + ParseEnumError { + attr: &'static str, + pos: (TextPos, TextPos), + #[source] + source: ParseEnumError, + }, #[error("invalid dom structure: {0}")] InvalidFormat(String), } @@ -60,6 +69,16 @@ impl DomConversionError { source: e, } } + + fn parse_enum_error(e: ParseEnumError, attr: &'static str, node: Node) -> Self { + let range = node.range(); + let doc = node.document(); + Self::ParseEnumError { + attr, + pos: (doc.text_pos_at(range.start), doc.text_pos_at(range.end)), + source: e, + } + } } impl Module { @@ -86,11 +105,18 @@ impl Module { .map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "size", root))?, None => return Err(DomConversionError::attr_not_found("size", root)), }; + let amod = root + .attribute("amod") + .map(|amod| { + amod.parse() + .map_err(|e| DomConversionError::parse_enum_error(e, "amod", root)) + }) + .transpose()?; Ok(Self { name, addr, size, - amod: todo!(), + amod, r#type: todo!(), desc: todo!(), elements_bitstring: todo!(), diff --git a/src/parser.rs b/src/parser.rs index 1259a2c..91e7ae8 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,7 +1,25 @@ //! Module for converting XML custom token string to rust types. +use std::any; + pub(crate) use parse_prefixed_u32::ParsePrefixedU32; pub use parse_prefixed_u32::ParsePrefixedU32Error; +use thiserror::Error; + +#[derive(Debug, Error, PartialEq)] +pub enum ParseEnumError { + #[error("{found} is not a valid variant of {type}")] + InvalidVariant { found: String, r#type: &'static str }, +} + +impl ParseEnumError { + pub fn invalid_variant(found: String) -> Self { + Self::InvalidVariant { + found, + r#type: any::type_name::(), + } + } +} mod parse_prefixed_u32 { use std::num; @@ -50,3 +68,44 @@ mod parse_prefixed_u32 { } } } + +mod parse_amodvalues { + use std::str::FromStr; + + use crate::types::AmodValues; + + use super::ParseEnumError; + + impl FromStr for AmodValues { + type Err = ParseEnumError; + + fn from_str(s: &str) -> Result { + match s { + "A16" => Ok(Self::A16), + "A24" => Ok(Self::A24), + "A32" => Ok(Self::A32), + "CRCSR" => Ok(Self::CRCSR), + "USER1" => Ok(Self::USER1), + "USER2" => Ok(Self::USER2), + s => Err(ParseEnumError::invalid_variant::(s.to_string())), + } + } + } + + #[cfg(test)] + mod test { + use super::AmodValues; + use super::ParseEnumError; + + #[test] + fn parse_amodvalues() { + assert_eq!("A32".parse(), Ok(AmodValues::A32)); + assert_eq!( + "A32aa".parse::(), + Err(ParseEnumError::invalid_variant::(String::from( + "A32aa" + ))) + ); + } + } +} diff --git a/src/types.rs b/src/types.rs index 087c0a8..2825cbc 100644 --- a/src/types.rs +++ b/src/types.rs @@ -116,7 +116,7 @@ pub struct Value { pub desc: Option } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum AmodValues { A16, A24,