Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support xsd all #112

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions xsd-parser/src/parser/all.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::cell::RefCell;

use roxmltree::Node;

use crate::parser::types::{RsEntity, Struct};
use crate::parser::utils::{elements_to_fields, get_documentation, get_parent_name};

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)),
})
}
92 changes: 0 additions & 92 deletions xsd-parser/src/parser/attribute_group.rs

This file was deleted.

4 changes: 1 addition & 3 deletions xsd-parser/src/parser/complex_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use roxmltree::Node;

use crate::parser::node_parser::parse_node;
use crate::parser::types::{RsEntity, Struct, StructField, StructFieldSource};
use crate::parser::utils::{attributes_to_fields, attribute_groups_to_aliases, get_documentation, get_parent_name};
use crate::parser::utils::{attributes_to_fields, get_documentation, get_parent_name};
use crate::parser::xsd_elements::{ElementType, XsdNode};

// A complex type can contain one and only one of the following elements,
Expand Down Expand Up @@ -45,7 +45,6 @@ pub fn parse_complex_type(node: &Node, parent: &Node) -> RsEntity {

return RsEntity::Struct(Struct {
fields: RefCell::new(fields),
attribute_groups: RefCell::new(attribute_groups_to_aliases(node)),
comment: get_documentation(node),
subtypes: vec![],
name: name.to_string(),
Expand All @@ -72,7 +71,6 @@ pub fn parse_complex_type(node: &Node, parent: &Node) -> RsEntity {
subtypes: vec![],
comment: get_documentation(node),
fields: RefCell::new(fields),
attribute_groups: RefCell::new(attribute_groups_to_aliases(node)),
})];
}
_ => (),
Expand Down
9 changes: 9 additions & 0 deletions xsd-parser/src/parser/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub fn parse_element(node: &Node, parent: &Node) -> RsEntity {
match parent.xsd_type() {
ElementType::Schema => parse_global_element(node),
ElementType::Sequence => parse_field_of_sequence(node, parent),
ElementType::All => parse_field_of_all(node, parent),
ElementType::Choice => parse_case_of_choice(node),
_ => element_default(node),
}
Expand Down Expand Up @@ -67,7 +68,15 @@ fn parse_case_of_choice(element: &Node) -> RsEntity {
})
}

fn parse_field_of_all(node: &Node, _: &Node) -> RsEntity {
parse_field_of_element_container(node)
}

fn parse_field_of_sequence(node: &Node, _: &Node) -> RsEntity {
parse_field_of_element_container(node)
}

fn parse_field_of_element_container(node: &Node) -> RsEntity {
let name = node
.attr_name()
.unwrap_or_else(|| node.attr_ref().unwrap_or("UNSUPPORTED_ELEMENT_NAME"))
Expand Down
4 changes: 1 addition & 3 deletions xsd-parser/src/parser/extension.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::parser::constants::{attribute, tag};
use crate::parser::node_parser::parse_node;
use crate::parser::types::{RsEntity, Struct, StructField, StructFieldSource};
use crate::parser::utils::{attributes_to_fields, attribute_groups_to_aliases, get_base, get_documentation};
use crate::parser::utils::{attributes_to_fields, get_base, get_documentation};
use crate::parser::xsd_elements::{ElementType, ExtensionType, XsdNode};
use roxmltree::Node;
use std::cell::RefCell;
Expand Down Expand Up @@ -41,7 +41,6 @@ fn simple_content_extension(node: &Node) -> RsEntity {
subtypes: vec![],
comment: get_documentation(node),
fields: RefCell::new(fields),
attribute_groups: RefCell::new(attribute_groups_to_aliases(node))
})
}

Expand Down Expand Up @@ -81,7 +80,6 @@ fn complex_content_extension(node: &Node) -> RsEntity {
RsEntity::Struct(Struct {
comment: get_documentation(node),
fields: RefCell::new(fields),
attribute_groups: RefCell::new(attribute_groups_to_aliases(node)),
..Default::default()
})
}
8 changes: 1 addition & 7 deletions xsd-parser/src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod all;
mod any;
mod any_attribute;
mod attribute;
mod attribute_group;
mod choice;
mod complex_content;
mod complex_type;
Expand Down Expand Up @@ -44,15 +44,9 @@ pub fn parse(text: &str) -> Result<RsFile, ()> {
map.extend(st.get_types_map());
}
}
for ag in &schema_rs.attribute_groups {
if let RsEntity::Struct(st) = ag {
map.extend(st.get_types_map());
}
}
for ty in &schema_rs.types {
if let RsEntity::Struct(st) = ty {
st.extend_base(&map);
st.extend_attribute_group(&map);
}
}

Expand Down
4 changes: 2 additions & 2 deletions xsd-parser/src/parser/node_parser.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
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;
use crate::parser::attribute_group::parse_attribute_group;
use crate::parser::choice::parse_choice;
use crate::parser::complex_content::parse_complex_content;
use crate::parser::complex_type::parse_complex_type;
Expand All @@ -23,10 +23,10 @@ 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),
AttributeGroup => parse_attribute_group(node, parent),
Choice => parse_choice(node),
ComplexContent => parse_complex_content(node),
ComplexType => parse_complex_type(node, parent),
Expand Down
3 changes: 1 addition & 2 deletions xsd-parser/src/parser/restriction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::parser::types::{
Enum, EnumCase, EnumSource, Facet, RsEntity, Struct, StructField, StructFieldSource,
TupleStruct,
};
use crate::parser::utils::{attributes_to_fields, attribute_groups_to_aliases, get_base, get_documentation, get_parent_name};
use crate::parser::utils::{attributes_to_fields, get_base, get_documentation, get_parent_name};
use crate::parser::xsd_elements::{ElementType, FacetType, RestrictionType, XsdNode};
use roxmltree::Node;

Expand Down Expand Up @@ -93,7 +93,6 @@ fn complex_content_restriction(node: &Node) -> RsEntity {
RsEntity::Struct(Struct {
comment: get_documentation(node),
fields: RefCell::new(fields),
attribute_groups: RefCell::new(attribute_groups_to_aliases(node)),
..Default::default()
})
}
Expand Down
8 changes: 0 additions & 8 deletions xsd-parser/src/parser/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ pub fn parse_schema<'input>(schema: &Node<'_, 'input>) -> RsFile<'input> {
})
.map(|node| parse_node(&node, schema))
.collect(),
attribute_groups: schema
.children()
.filter(|n| {
n.is_element()
&& n.xsd_type() == ElementType::AttributeGroup
})
.map(|node| parse_node(&node, schema))
.collect(),
}
}

Expand Down
27 changes: 2 additions & 25 deletions xsd-parser/src/parser/sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ 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};
use crate::parser::types::{RsEntity, Struct};
use crate::parser::utils::{elements_to_fields, get_documentation, get_parent_name};

pub fn parse_sequence(sequence: &Node, parent: &Node) -> RsEntity {
let name = get_parent_name(sequence);
Expand All @@ -14,26 +12,5 @@ pub fn parse_sequence(sequence: &Node, parent: &Node) -> RsEntity {
comment: get_documentation(parent),
subtypes: vec![],
fields: RefCell::new(elements_to_fields(sequence, name)),
..Default::default()
})
}

fn elements_to_fields(sequence: &Node, parent_name: &str) -> Vec<StructField> {
sequence
.children()
.filter(|n| n.is_element() && n.xsd_type() != ElementType::Annotation)
.map(|n| match parse_node(&n, sequence) {
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, sequence)),
})
.collect()
}
19 changes: 0 additions & 19 deletions xsd-parser/src/parser/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub struct RsFile<'input> {
pub name: String,
pub namespace: Option<String>,
pub types: Vec<RsEntity>,
pub attribute_groups: Vec<RsEntity>,
pub target_ns: Option<Namespace<'input>>,
pub xsd_ns: Option<Namespace<'input>>,
}
Expand All @@ -20,7 +19,6 @@ pub struct Struct {
pub name: String,
pub comment: Option<String>,
pub fields: RefCell<Vec<StructField>>,
pub attribute_groups: RefCell<Vec<Alias>>,
pub subtypes: Vec<RsEntity>,
}

Expand Down Expand Up @@ -76,23 +74,6 @@ impl Struct {
}
}
}

pub fn extend_attribute_group(&self, types: &HashMap<&String, &Self>) {
let mut fields = self
.attribute_groups
.borrow()
.iter()
.flat_map(|f| {
let key = f.original.split(':').last().unwrap().to_string();
types
.get(&key)
.map(|s| s.fields.borrow().clone())
.unwrap_or_else(Vec::new)
})
.collect::<Vec<StructField>>();

self.fields.borrow_mut().append(&mut fields);
}
}

#[derive(Debug, Clone, Default)]
Expand Down
33 changes: 20 additions & 13 deletions xsd-parser/src/parser/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use roxmltree::{Namespace, Node};

use crate::parser::constants::attribute;
use crate::parser::node_parser::parse_node;
use crate::parser::types::{Enum, RsEntity, StructField, StructFieldSource, Alias};
use crate::parser::types::{Enum, RsEntity, StructField, StructFieldSource, TypeModifier};
use crate::parser::xsd_elements::{ElementType, XsdNode};

pub fn target_namespace<'a, 'input>(node: &Node<'a, 'input>) -> Option<&'a Namespace<'input>> {
Expand Down Expand Up @@ -60,18 +60,6 @@ pub fn attributes_to_fields(node: &Node) -> Vec<StructField> {
.collect()
}

pub fn attribute_groups_to_aliases(node: &Node) -> Vec<Alias> {
node.children()
.filter(|n| {
n.xsd_type() == ElementType::AttributeGroup
})
.map(|n| match parse_node(&n, node) {
RsEntity::Alias(a) => a,
_ => unreachable!("Invalid attribute group parsing: {:?}", n),
})
.collect()
}

pub fn enum_to_field(en: Enum) -> StructField {
StructField {
name: en.name.clone(),
Expand All @@ -81,3 +69,22 @@ pub fn enum_to_field(en: Enum) -> StructField {
..Default::default()
}
}

pub fn elements_to_fields(node: &Node, parent_name: &str) -> Vec<StructField> {
node.children()
.filter(|n| n.is_element() && n.xsd_type() != ElementType::Annotation)
.map(|n| match parse_node(&n, node) {
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, node)),
})
.collect()
}
Loading