new: Module.amod parsing

This commit is contained in:
Wataru Otsubo 2025-01-30 01:18:31 +09:00
parent 371068e363
commit 8188b4fef8
3 changed files with 88 additions and 3 deletions

View file

@ -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!(),

View file

@ -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<T>(found: String) -> Self {
Self::InvalidVariant {
found,
r#type: any::type_name::<T>(),
}
}
}
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<Self, Self::Err> {
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::<AmodValues>(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::<AmodValues>(),
Err(ParseEnumError::invalid_variant::<AmodValues>(String::from(
"A32aa"
)))
);
}
}
}

View file

@ -116,7 +116,7 @@ pub struct Value {
pub desc: Option<String>
}
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum AmodValues {
A16,
A24,