diff --git a/xsd-parser/src/parser/all.rs b/xsd-parser/src/parser/all.rs new file mode 100644 index 00000000..dbbd42b0 --- /dev/null +++ b/xsd-parser/src/parser/all.rs @@ -0,0 +1,39 @@ +use std::cell::RefCell; + +use roxmltree::Node; + +use crate::parser::node_parser::parse_node; +use crate::parser::types::{RsEntity, Struct, StructField, TypeModifier}; +use crate::parser::utils::{enum_to_field, get_documentation, get_parent_name}; +use crate::parser::xsd_elements::{ElementType, XsdNode}; + +pub fn parse_all(node: &Node, parent: &Node) -> RsEntity { + let name = get_parent_name(node); + RsEntity::Struct(Struct { + name: name.into(), + comment: get_documentation(parent), + subtypes: vec![], + fields: RefCell::new(elements_to_fields(node, name)), + ..Default::default() + }) +} + +fn elements_to_fields(choice: &Node, parent_name: &str) -> Vec { + choice + .children() + .filter(|n| n.is_element() && n.xsd_type() != ElementType::Annotation) + .map(|n| match parse_node(&n, choice) { + RsEntity::StructField(mut sf) => { + if sf.type_name.ends_with(parent_name) { + sf.type_modifiers.push(TypeModifier::Recursive) + } + sf + } + RsEntity::Enum(mut en) => { + en.name = format!("{}Choice", parent_name); + enum_to_field(en) + } + _ => unreachable!("\nError: {:?}\n{:?}", n, parse_node(&n, choice)), + }) + .collect() +} diff --git a/xsd-parser/src/parser/element.rs b/xsd-parser/src/parser/element.rs index 69794ab4..df840312 100644 --- a/xsd-parser/src/parser/element.rs +++ b/xsd-parser/src/parser/element.rs @@ -14,6 +14,7 @@ const SUPPORTED_CONTENT_TYPES: [ElementType; 2] = pub fn parse_element(node: &Node, parent: &Node) -> RsEntity { match parent.xsd_type() { ElementType::Schema => parse_global_element(node), + ElementType::All => parse_field_of_sequence(node, parent), ElementType::Sequence => parse_field_of_sequence(node, parent), ElementType::Choice => parse_case_of_choice(node), _ => element_default(node), diff --git a/xsd-parser/src/parser/mod.rs b/xsd-parser/src/parser/mod.rs index e4192187..e7215ad8 100644 --- a/xsd-parser/src/parser/mod.rs +++ b/xsd-parser/src/parser/mod.rs @@ -1,4 +1,5 @@ mod any; +mod all; mod any_attribute; mod attribute; mod attribute_group; diff --git a/xsd-parser/src/parser/node_parser.rs b/xsd-parser/src/parser/node_parser.rs index f1ae89cf..eab87b25 100644 --- a/xsd-parser/src/parser/node_parser.rs +++ b/xsd-parser/src/parser/node_parser.rs @@ -1,5 +1,6 @@ use roxmltree::Node; +use crate::parser::all::parse_all; use crate::parser::any::parse_any; use crate::parser::any_attribute::parse_any_attribute; use crate::parser::attribute::parse_attribute; @@ -23,6 +24,7 @@ pub fn parse_node(node: &Node, parent: &Node) -> RsEntity { use ElementType::*; match node.xsd_type() { + All => parse_all(node, parent), Any => parse_any(node), AnyAttribute => parse_any_attribute(node), Attribute => parse_attribute(node, parent),