mirror of
https://gitlab.cern.ch/wotsubo/endcap-sl-software-ri-generator.git
synced 2025-02-23 00:57:08 +09:00
wip(converter): until Block converter (next: Register)
This commit is contained in:
parent
a8071b359d
commit
8fee555860
5 changed files with 310 additions and 28 deletions
290
src/converter.rs
290
src/converter.rs
|
@ -1,12 +1,15 @@
|
|||
//! Convert DOM to register interface, complementing optional parameters.
|
||||
|
||||
use std::num;
|
||||
use std::{num, str};
|
||||
|
||||
use roxmltree::{Node, TextPos};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::parser::{ParseEnumError, ParsePrefixedU32, ParsePrefixedU32Error};
|
||||
use crate::types::Module;
|
||||
use crate::types::{
|
||||
BitString, Block, DataType, Field, Fifo, Memory, Module, ModuleBlockElements, MultipleParams,
|
||||
Register, Value,
|
||||
};
|
||||
|
||||
#[derive(Debug, Error, PartialEq)]
|
||||
pub enum DomConversionError {
|
||||
|
@ -36,8 +39,13 @@ pub enum DomConversionError {
|
|||
#[source]
|
||||
source: ParseEnumError,
|
||||
},
|
||||
#[error("invalid dom structure: {0}")]
|
||||
InvalidFormat(String),
|
||||
#[error("invalid node {found}: {start} - {end}", start = pos.0, end = pos.1)]
|
||||
InvalidNode {
|
||||
pos: (TextPos, TextPos),
|
||||
found: String,
|
||||
},
|
||||
#[error("other dom conversion error: {0}")]
|
||||
OtherError(String),
|
||||
}
|
||||
|
||||
impl DomConversionError {
|
||||
|
@ -79,48 +87,278 @@ impl DomConversionError {
|
|||
source: e,
|
||||
}
|
||||
}
|
||||
|
||||
fn invalid_node(found: String, node: Node) -> Self {
|
||||
let range = node.range();
|
||||
let doc = node.document();
|
||||
Self::InvalidNode {
|
||||
pos: (doc.text_pos_at(range.start), doc.text_pos_at(range.end)),
|
||||
found,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod util {
|
||||
use roxmltree::Node;
|
||||
|
||||
use crate::types::{DataType, RwSpecifier};
|
||||
|
||||
use super::DomConversionError;
|
||||
|
||||
pub(crate) fn get_name(node: Node) -> Result<String, DomConversionError> {
|
||||
match node.attribute("name") {
|
||||
Some(name) => Ok(name.to_string()),
|
||||
None => Err(DomConversionError::attr_not_found("name", node)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_type(node: Node) -> Option<Result<DataType, DomConversionError>> {
|
||||
node.attribute("type").map(|x| {
|
||||
x.parse()
|
||||
.map_err(|e| DomConversionError::parse_enum_error(e, "type", node))
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn get_modf(node: Node) -> Option<Result<RwSpecifier, DomConversionError>> {
|
||||
node.attribute("modf").map(|x| {
|
||||
x.parse()
|
||||
.map_err(|e| DomConversionError::parse_enum_error(e, "modf", node))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
pub fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
assert!(node.parent().unwrap().is_root());
|
||||
assert_eq!(node.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") {
|
||||
let name = util::get_name(node)?;
|
||||
let addr = match node.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)),
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "addr", node))?,
|
||||
None => return Err(DomConversionError::attr_not_found("addr", node)),
|
||||
};
|
||||
let size = match root.attribute("size") {
|
||||
let size = match node.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)),
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "size", node))?,
|
||||
None => return Err(DomConversionError::attr_not_found("size", node)),
|
||||
};
|
||||
let amod = root
|
||||
let amod = node
|
||||
.attribute("amod")
|
||||
.map(|amod| {
|
||||
amod.parse()
|
||||
.map_err(|e| DomConversionError::parse_enum_error(e, "amod", root))
|
||||
.map_err(|e| DomConversionError::parse_enum_error(e, "amod", node))
|
||||
})
|
||||
.transpose()?;
|
||||
let r#type = util::get_type(node).transpose()?;
|
||||
|
||||
let child_bitstrings = node
|
||||
.children()
|
||||
.filter(|node| node.is_element())
|
||||
.filter(|node| node.tag_name().name().eq("bitstring"))
|
||||
.map(|node| BitString::from_xml_dom(node))
|
||||
.collect::<Result<_, _>>()?;
|
||||
let child_other = node
|
||||
.children()
|
||||
.filter(|node| node.is_element())
|
||||
.map(|node| ModuleBlockElements::from_xml_dom(node))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
Ok(Self {
|
||||
name,
|
||||
addr,
|
||||
size,
|
||||
amod,
|
||||
r#type: todo!(),
|
||||
desc: todo!(),
|
||||
elements_bitstring: todo!(),
|
||||
elements_other: todo!(),
|
||||
r#type,
|
||||
desc: node.attribute("desc").map(str::to_string),
|
||||
elements_bitstring: child_bitstrings,
|
||||
elements_other: child_other,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleBlockElements {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
match node.tag_name().name() {
|
||||
"block" => Ok(Self::Block(Block::from_xml_dom(node)?)),
|
||||
"register" => Ok(Self::Register(Register::from_xml_dom(node)?)),
|
||||
"memory" => Ok(Self::Memory(Memory::from_xml_dom(node)?)),
|
||||
"fifo" => Ok(Self::Fifo(Fifo::from_xml_dom(node)?)),
|
||||
s => Err(DomConversionError::invalid_node(s.to_string(), node)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BitString {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
let name = util::get_name(node)?;
|
||||
let size = node
|
||||
.attribute("size")
|
||||
.map(|addr| {
|
||||
addr.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "size", node))
|
||||
})
|
||||
.transpose()?;
|
||||
let mask = node
|
||||
.attribute("mask")
|
||||
.map(|addr| {
|
||||
addr.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "mask", node))
|
||||
})
|
||||
.transpose()?;
|
||||
let modf = node
|
||||
.attribute("modf")
|
||||
.map(|addr| {
|
||||
addr.parse()
|
||||
.map_err(|e| DomConversionError::parse_enum_error(e, "modf", node))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let children = node
|
||||
.children()
|
||||
.filter(|node| node.is_element() && node.tag_name().name().eq("field"))
|
||||
.map(|node| Field::from_xml_dom(node))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
Ok(Self {
|
||||
name,
|
||||
size,
|
||||
mask,
|
||||
modf,
|
||||
desc: node.attribute("desc").map(str::to_string),
|
||||
elements_field: children,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
let name = util::get_name(node)?;
|
||||
let addr = match node.attribute("addr") {
|
||||
Some(addr) => addr
|
||||
.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "addr", node))?,
|
||||
None => {
|
||||
// derive from parent
|
||||
todo!("need to confirm")
|
||||
}
|
||||
};
|
||||
let r#type = match util::get_type(node).transpose()? {
|
||||
Some(x) => Some(x),
|
||||
None => node
|
||||
.ancestors()
|
||||
.filter_map(util::get_type)
|
||||
.next()
|
||||
.transpose()?,
|
||||
};
|
||||
let modf = match util::get_modf(node).transpose()? {
|
||||
Some(x) => Some(x),
|
||||
None => node
|
||||
.ancestors()
|
||||
.filter_map(util::get_modf)
|
||||
.next()
|
||||
.transpose()?,
|
||||
};
|
||||
let multiple = MultipleParams::from_xml_dom(node)?;
|
||||
let decoder = match node.attribute("decoder") {
|
||||
Some(s) => s.to_string(),
|
||||
None => match node
|
||||
.ancestors()
|
||||
.filter_map(|node| node.attribute("decoder"))
|
||||
.next()
|
||||
{
|
||||
Some(s) => Ok(s.to_string()),
|
||||
None => Err(DomConversionError::OtherError(
|
||||
"decoder format is not yet fixed".to_string(),
|
||||
)),
|
||||
}?,
|
||||
};
|
||||
let size = match node.attribute("size") {
|
||||
Some(addr) => addr
|
||||
.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "size", node))?,
|
||||
None => return Err(DomConversionError::attr_not_found("size", node)),
|
||||
};
|
||||
let desc = node.attribute("desc").map(str::to_string);
|
||||
|
||||
let children = node
|
||||
.children()
|
||||
.filter(|node| node.is_element())
|
||||
.map(|node| ModuleBlockElements::from_xml_dom(node))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
Ok(Block {
|
||||
name,
|
||||
addr,
|
||||
r#type,
|
||||
modf,
|
||||
multiple,
|
||||
decoder,
|
||||
size,
|
||||
desc,
|
||||
elements: children,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Register {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
todo!("do here next")
|
||||
}
|
||||
}
|
||||
|
||||
impl Memory {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Fifo {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Field {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Self, DomConversionError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl MultipleParams {
|
||||
pub(crate) fn from_xml_dom(node: Node) -> Result<Option<Self>, DomConversionError> {
|
||||
let multiple = match node
|
||||
.attribute("multiple")
|
||||
.map(|x| {
|
||||
x.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "multiple", node))
|
||||
})
|
||||
.transpose()?
|
||||
{
|
||||
Some(x) => x,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let offset = match node
|
||||
.attribute("offset")
|
||||
.map(|x| {
|
||||
x.parse_prefixed_u32()
|
||||
.map_err(|e| DomConversionError::parse_prefixed_u32_error(e, "offset", node))
|
||||
})
|
||||
.transpose()?
|
||||
{
|
||||
Some(x) => x,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
Ok(Some(MultipleParams { multiple, offset }))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Root document [`types::Module::from_xml_dom`]
|
||||
|
||||
pub mod types;
|
||||
pub mod parser;
|
||||
pub mod converter;
|
||||
|
|
|
@ -18,6 +18,8 @@ fn main() {
|
|||
{
|
||||
let root = doc.root_element();
|
||||
println!("tag: {:?}", root.tag_name());
|
||||
let root_childs = root.children().filter(|node| node.is_element());
|
||||
println!("children: {:?}", root_childs);
|
||||
}
|
||||
|
||||
let register_map = types::Module::from_xml_dom(doc.root_element()).unwrap();
|
||||
|
|
|
@ -109,3 +109,43 @@ mod parse_amodvalues {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod parse_datatype {
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::types::DataType;
|
||||
|
||||
use super::ParseEnumError;
|
||||
|
||||
impl FromStr for DataType {
|
||||
type Err = ParseEnumError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"D32" => Ok(Self::D32),
|
||||
s => Err(ParseEnumError::invalid_variant::<Self>(s.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod parse_rw_specifier {
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::types::RwSpecifier;
|
||||
|
||||
use super::ParseEnumError;
|
||||
|
||||
impl FromStr for RwSpecifier {
|
||||
type Err = ParseEnumError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"R" => Ok(Self::R),
|
||||
"W" => Ok(Self::W),
|
||||
"RW" => Ok(Self::RW),
|
||||
s => Err(ParseEnumError::invalid_variant::<Self>(s.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ pub struct Block {
|
|||
/// Fill this with proper calc.
|
||||
pub addr: u32,
|
||||
/// Fill this with proper calc.
|
||||
pub r#type: DataType,
|
||||
pub r#type: Option<DataType>,
|
||||
/// Fill this with proper calc.
|
||||
pub modf: RwSpecifier,
|
||||
pub modf: Option<RwSpecifier>,
|
||||
// TODO: should this be expanded?
|
||||
pub multiple: Option<MultipleParams>,
|
||||
// TODO
|
||||
|
|
Loading…
Reference in a new issue