mirror of
https://gitlab.cern.ch/wotsubo/endcap-sl-software-ri-generator.git
synced 2025-02-23 00:57:08 +09:00
add(converter): until top module, size attr
This commit is contained in:
parent
f2a7a5a28b
commit
b549445b26
5 changed files with 188 additions and 1 deletions
56
Cargo.lock
generated
56
Cargo.lock
generated
|
@ -7,6 +7,25 @@ name = "endcap-sl-register-interface-generator"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"roxmltree",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -14,3 +33,40 @@ name = "roxmltree"
|
|||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
||||
|
|
|
@ -13,3 +13,4 @@ path = "src/lib.rs"
|
|||
|
||||
[dependencies]
|
||||
roxmltree = "0.20"
|
||||
thiserror = "2.0"
|
||||
|
|
127
src/converter.rs
Normal file
127
src/converter.rs
Normal file
|
@ -0,0 +1,127 @@
|
|||
use std::num;
|
||||
|
||||
use roxmltree::{Node, TextPos};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::types::Module;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DomConversionError {
|
||||
#[error("attribute {attr} not found in element: {start} - {end}", start = pos.0, end = pos.1)]
|
||||
AttributeNotFound {
|
||||
attr: &'static str,
|
||||
pos: (TextPos, TextPos),
|
||||
},
|
||||
#[error("string conversion error: {start} - {end}", start = pos.0, end = pos.1)]
|
||||
ParseIntError {
|
||||
attr: &'static str,
|
||||
pos: (TextPos, TextPos),
|
||||
#[source]
|
||||
source: num::ParseIntError,
|
||||
},
|
||||
#[error("string conversion error: {start} - {end}", start = pos.0, end = pos.1)]
|
||||
ParsePrefixedU32Error {
|
||||
attr: &'static str,
|
||||
pos: (TextPos, TextPos),
|
||||
#[source]
|
||||
source: ParsePrefixedU32Error,
|
||||
},
|
||||
#[error("invalid dom structure: {0}")]
|
||||
InvalidFormat(String),
|
||||
}
|
||||
|
||||
impl DomConversionError {
|
||||
fn attr_not_found(attr: &'static str, node: Node) -> Self {
|
||||
let range = node.range();
|
||||
let doc = node.document();
|
||||
Self::AttributeNotFound {
|
||||
attr,
|
||||
pos: (doc.text_pos_at(range.start), doc.text_pos_at(range.end)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_int_error(e: num::ParseIntError, attr: &'static str, node: Node) -> Self {
|
||||
let range = node.range();
|
||||
let doc = node.document();
|
||||
Self::ParseIntError {
|
||||
attr,
|
||||
pos: (doc.text_pos_at(range.start), doc.text_pos_at(range.end)),
|
||||
source: e,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_prefixed_u32_error(e: ParsePrefixedU32Error, attr: &'static str, node: Node) -> Self {
|
||||
let range = node.range();
|
||||
let doc = node.document();
|
||||
Self::ParsePrefixedU32Error {
|
||||
attr,
|
||||
pos: (doc.text_pos_at(range.start), doc.text_pos_at(range.end)),
|
||||
source: e,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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<u32, ParsePrefixedU32Error>;
|
||||
}
|
||||
|
||||
impl ParsePrefixedU32 for &str {
|
||||
fn parse_prefixed_u32(&self) -> Result<u32, ParsePrefixedU32Error> {
|
||||
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<Self, DomConversionError> {
|
||||
assert!(root.parent().unwrap().is_root());
|
||||
assert_eq!(root.tag_name().name(), "module");
|
||||
|
||||
let name = root.tag_name().name();
|
||||
println!("{}", name);
|
||||
|
||||
let name = match root.attribute("name") {
|
||||
Some(name) => name.to_string(),
|
||||
None => return Err(DomConversionError::attr_not_found("name", root)),
|
||||
};
|
||||
let addr = match root.attribute("addr") {
|
||||
Some(addr) => addr
|
||||
.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "addr", root))?,
|
||||
None => return Err(DomConversionError::attr_not_found("addr", root)),
|
||||
};
|
||||
let size = match root.attribute("size") {
|
||||
Some(addr) => addr
|
||||
.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "size", root))?,
|
||||
None => return Err(DomConversionError::attr_not_found("size", root)),
|
||||
};
|
||||
Ok(Self {
|
||||
name,
|
||||
addr,
|
||||
size,
|
||||
amod: todo!(),
|
||||
r#type: todo!(),
|
||||
desc: todo!(),
|
||||
elements_bitstring: todo!(),
|
||||
elements_other: todo!(),
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
pub mod types;
|
||||
pub mod converter;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fs;
|
||||
|
||||
use endcap_sl_register_interface_generator;
|
||||
use endcap_sl_register_interface_generator::types;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
|
@ -19,4 +19,6 @@ fn main() {
|
|||
let root = doc.root_element();
|
||||
println!("tag: {:?}", root.tag_name());
|
||||
}
|
||||
|
||||
let register_map = types::Module::from_xml_dom(doc.root_element()).unwrap();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue