Skip to content
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
9 changes: 4 additions & 5 deletions xml_schema/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ readme = "../README.md"
exclude = ["/tests"]

[dependencies]
xml-schema-derive = { version = "0.3.0", path = "../xml_schema_derive", optional = true }

[dev-dependencies]
log = "0.4"
xml-rs = "0.8"
xml-schema-derive = { version = "0.3.0", path = "../xml_schema_derive" }
yaserde_derive = { version = "0.9" }
yaserde = { version = "0.9" }
log = "0.4"
reqwest = { version = "0.11", default-features = false, features = ["blocking"] }

[dev-dependencies]
7 changes: 4 additions & 3 deletions xml_schema/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cfg(feature = "xml_schema_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate xml_schema_derive;
extern crate yaserde_derive;

mod xsd;
pub use xsd::*;
20 changes: 20 additions & 0 deletions xml_schema/src/xsd/annotation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use crate::xsd::attribute::Attribute;

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(
rename = "annotation"
prefix = "xs",
namespace = "xs: http://www.w3.org/2001/XMLSchema"
)]
pub struct Annotation {
#[yaserde(attribute)]
pub id: Option<String>,
#[yaserde(rename = "attribute")]
pub attributes: Vec<Attribute>,
#[yaserde(
rename = "documentation"
prefix = "xs",
namespace = "xs: http://www.w3.org/2001/XMLSchema"
)]
pub documentation: Vec<String>,
}
33 changes: 33 additions & 0 deletions xml_schema/src/xsd/attribute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use crate::xsd::simple_type::SimpleType;

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(
rename = "attribute",
prefix = "xs",
namespace = "xs: http://www.w3.org/2001/XMLSchema"
)]
pub struct Attribute {
#[yaserde(prefix = "xs", attribute)]
pub name: Option<String>,
#[yaserde(rename = "type", attribute)]
pub kind: Option<String>,
// #[yaserde(attribute)]
// pub default: Option<String>,
// #[yaserde(attribute)]
// pub fixed: Option<String>,
#[yaserde(rename = "use", attribute)]
pub required: Required,
#[yaserde(rename = "ref", attribute)]
pub reference: Option<String>,
#[yaserde(rename = "simpleType")]
pub simple_type: Option<SimpleType>,
}

#[derive(Clone, Debug, Default, PartialEq, YaDeserialize)]
pub enum Required {
#[default]
#[yaserde(rename = "optional")]
Optional,
#[yaserde(rename = "required")]
Required,
}
7 changes: 7 additions & 0 deletions xml_schema/src/xsd/complex_content.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use crate::xsd::extension::Extension;

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(prefix = "xs", namespace = "xs: http://www.w3.org/2001/XMLSchema")]
pub struct ComplexContent {
pub extension: Option<Extension>,
}
24 changes: 24 additions & 0 deletions xml_schema/src/xsd/complex_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::xsd::{
annotation::Annotation, attribute::Attribute, complex_content::ComplexContent,
sequence::Sequence, simple_content::SimpleContent,
};

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(
rename = "complexType"
prefix = "xs",
namespace = "xs: http://www.w3.org/2001/XMLSchema"
)]
pub struct ComplexType {
#[yaserde(attribute)]
pub name: String,
#[yaserde(rename = "attribute")]
pub attributes: Vec<Attribute>,
pub sequence: Option<Sequence>,
#[yaserde(rename = "simpleContent")]
pub simple_content: Option<SimpleContent>,
#[yaserde(rename = "complexContent")]
pub complex_content: Option<ComplexContent>,
#[yaserde(rename = "annotation")]
pub annotation: Option<Annotation>,
}
File renamed without changes.
37 changes: 37 additions & 0 deletions xml_schema/src/xsd/element.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::xsd::{
annotation::Annotation, complex_type::ComplexType, max_occurences::MaxOccurences,
simple_type::SimpleType,
};

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(prefix = "xs", namespace = "xs: http://www.w3.org/2001/XMLSchema")]
pub struct Element {
#[yaserde(attribute)]
pub name: String,
#[yaserde(rename = "type", attribute)]
pub kind: Option<String>,
#[yaserde(rename = "ref", attribute)]
pub refers: Option<String>,
#[yaserde(rename = "minOccurs", attribute)]
pub min_occurences: Option<u64>,
#[yaserde(rename = "maxOccurs", attribute)]
pub max_occurences: Option<MaxOccurences>,
#[yaserde(rename = "complexType")]
pub complex_type: Option<ComplexType>,
#[yaserde(rename = "simpleType")]
pub simple_type: Option<SimpleType>,
#[yaserde(rename = "annotation")]
pub annotation: Option<Annotation>,
}

impl Element {
pub fn get_refers(&self) -> Option<&str> {
self.refers.as_ref().and_then(|refers| {
if refers.is_empty() {
None
} else {
Some(refers.as_str())
}
})
}
}
18 changes: 18 additions & 0 deletions xml_schema/src/xsd/extension.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use crate::xsd::{attribute::Attribute, group::Group, sequence::Sequence};

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(
root = "extension",
prefix = "xs",
namespace = "xs: http://www.w3.org/2001/XMLSchema"
)]
pub struct Extension {
#[yaserde(attribute)]
pub base: String,
#[yaserde(rename = "attribute")]
pub attributes: Vec<Attribute>,
#[yaserde(rename = "sequence")]
pub sequences: Vec<Sequence>,
#[yaserde(rename = "group")]
pub group: Option<Group>,
}
12 changes: 12 additions & 0 deletions xml_schema/src/xsd/group.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::xsd::sequence::Sequence;

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(prefix = "xs", namespace = "xs: http://www.w3.org/2001/XMLSchema")]
pub struct Group {
#[yaserde(attribute)]
pub name: Option<String>,
#[yaserde(attribute, rename = "ref")]
pub reference: Option<String>,
#[yaserde()]
pub sequence: Option<Sequence>,
}
File renamed without changes.
6 changes: 6 additions & 0 deletions xml_schema/src/xsd/list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(prefix = "xs", namespace = "xs: http://www.w3.org/2001/XMLSchema")]
pub struct List {
#[yaserde(rename = "itemType", attribute)]
pub item_type: String,
}
96 changes: 96 additions & 0 deletions xml_schema/src/xsd/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
mod annotation;
mod attribute;
mod attribute_group;
mod complex_content;
mod complex_type;
mod element;
mod extension;
mod group;
mod import;
mod list;
mod max_occurences;
mod qualification;
mod restriction;
mod schema;
mod sequence;
mod simple_content;
mod simple_type;
mod union;
mod xsd_context;

pub use annotation::*;
pub use attribute::*;
pub use attribute_group::*;
pub use complex_content::*;
pub use complex_type::*;
pub use element::*;
pub use extension::*;
pub use group::*;
pub use import::*;
pub use list::*;
pub use max_occurences::*;
pub use qualification::*;
pub use restriction::*;
pub use schema::*;
pub use sequence::*;
pub use simple_content::*;
pub use simple_type::*;
pub use union::*;
pub use xsd_context::*;

use std::collections::BTreeMap;
use std::fs;
use yaserde::de::from_str;

#[derive(Clone, Debug)]
pub struct Xsd {
pub name: String,
pub context: XsdContext,
pub schema: schema::Schema,
}

impl Xsd {
pub fn new(
name: String,
content: &str,
module_namespace_mappings: &BTreeMap<String, String>,
) -> Result<Self, String> {
let context = XsdContext::new(content)?;
let context = context.with_module_namespace_mappings(module_namespace_mappings);
let schema: schema::Schema = from_str(content)?;

Ok(Xsd {
name,
context,
schema,
})
}

pub fn new_from_file(
name: String,
source: &str,
module_namespace_mappings: &BTreeMap<String, String>,
) -> Result<Self, String> {
let content = if source.starts_with("http://") || source.starts_with("https://") {
log::info!("Load HTTP schema {}", source);
reqwest::blocking::get(source)
.map_err(|e| e.to_string())?
.text()
.map_err(|e| e.to_string())?
} else {
let path = std::env::current_dir().unwrap();
log::info!("The current directory is {}", path.display());

fs::read_to_string(source).map_err(|e| e.to_string())?
};

// skip BOM header, can be present on some files
let content = if content.as_bytes()[0..3] == [0xef, 0xbb, 0xbf] {
content[3..].to_owned()
} else {
content
};

Xsd::new(name, &content, module_namespace_mappings)
}
}
6 changes: 6 additions & 0 deletions xml_schema/src/xsd/restriction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(prefix = "xs", namespace = "xs: http://www.w3.org/2001/XMLSchema")]
pub struct Restriction {
#[yaserde(rename = "base", attribute)]
pub base: Option<String>,
}
32 changes: 32 additions & 0 deletions xml_schema/src/xsd/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use crate::xsd::{
attribute, attribute_group, complex_type, element, group, import, qualification, simple_type,
};

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(
root="schema"
prefix="xs",
namespace="xs: http://www.w3.org/2001/XMLSchema",
)]
pub struct Schema {
#[yaserde(rename = "targetNamespace", attribute)]
pub target_namespace: Option<String>,
#[yaserde(rename = "elementFormDefault", attribute)]
pub element_form_default: Option<qualification::Qualification>,
#[yaserde(rename = "attributeFormDefault", attribute)]
pub attribute_form_default: Option<qualification::Qualification>,
#[yaserde(rename = "import")]
pub imports: Vec<import::Import>,
#[yaserde(rename = "element")]
pub elements: Vec<element::Element>,
#[yaserde(rename = "simpleType")]
pub simple_type: Vec<simple_type::SimpleType>,
#[yaserde(rename = "complexType")]
pub complex_type: Vec<complex_type::ComplexType>,
#[yaserde(rename = "attribute")]
pub attributes: Vec<attribute::Attribute>,
#[yaserde(rename = "attributeGroup")]
pub attribute_group: Vec<attribute_group::AttributeGroup>,
#[yaserde(rename = "group")]
pub group: Vec<group::Group>,
}
8 changes: 8 additions & 0 deletions xml_schema/src/xsd/sequence.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use crate::xsd::element::Element;

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(prefix = "xs", namespace = "xs: http://www.w3.org/2001/XMLSchema")]
pub struct Sequence {
#[yaserde(rename = "element")]
pub elements: Vec<Element>,
}
8 changes: 8 additions & 0 deletions xml_schema/src/xsd/simple_content.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use crate::xsd::extension::Extension;

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(prefix = "xs", namespace = "xs: http://www.w3.org/2001/XMLSchema")]
pub struct SimpleContent {
#[yaserde(prefix = "xs", rename = "extension")]
pub extension: Extension,
}
11 changes: 11 additions & 0 deletions xml_schema/src/xsd/simple_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use crate::xsd::{list::List, restriction::Restriction, union::Union};

#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
#[yaserde(prefix = "xs", namespace = "xs: http://www.w3.org/2001/XMLSchema")]
pub struct SimpleType {
#[yaserde(attribute)]
pub name: String,
pub restriction: Option<Restriction>,
pub list: Option<List>,
pub union: Option<Union>,
}
File renamed without changes.
1 change: 1 addition & 0 deletions xml_schema_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ proc-macro = true
default = ["reqwest/default-tls"]

[dependencies]
xml-schema = { path = "../xml_schema"}
darling = "0.20.3"
heck = "0.4"
log = "0.4"
Expand Down
7 changes: 4 additions & 3 deletions xml_schema_derive/src/expander.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{attribute::XmlSchemaAttributes, xsd::Xsd};
use crate::{attribute::XmlSchemaAttributes, xsd::implement_xsd};
use proc_macro2::TokenStream;
use syn::{token::Pub, Visibility};

use xml_schema::Xsd;

pub fn expand_derive(attributes: &XmlSchemaAttributes) -> Result<TokenStream, String> {
let _ = simple_logger::init_with_level(attributes.log_level());
log::info!("{:?}", attributes);
Expand All @@ -10,11 +12,10 @@ pub fn expand_derive(attributes: &XmlSchemaAttributes) -> Result<TokenStream, St

let xsd = Xsd::new_from_file(
attributes.module_name(),
vis,
&attributes.source,
&attributes.module_namespace_mappings(),
)?;
let generated = xsd.implement(&attributes.target_prefix);
let generated = implement_xsd(&xsd, vis, &attributes.target_prefix);

if let Some(store_generated_code) = &attributes.store_generated_code {
std::fs::write(store_generated_code, generated.to_string()).map_err(|e| e.to_string())?;
Expand Down
2 changes: 1 addition & 1 deletion xml_schema_derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern crate proc_macro;
#[macro_use]
extern crate quote;
#[macro_use]

extern crate yaserde_derive;

use crate::attribute::XmlSchemaAttributes;
Expand Down
Loading