Skip to content

Commit 1fb6641

Browse files
committed
WIP
1 parent 21f7800 commit 1fb6641

69 files changed

Lines changed: 23227 additions & 11768 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

xsd-parser/src/config/generator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ pub struct TypePostfix {
325325
/// Postfix for the type that is used as content for [`Nillable`](xsd_parser_types::xml::Nillable) elements.
326326
pub nillable_content: String,
327327

328-
/// Postfix for concrete elements in a substitution group.
328+
/// Postfix for concrete elements in a substitution group or concrete types of a dynamic type.
329329
pub dynamic_element: String,
330330
}
331331

xsd-parser/src/config/interpreter.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ pub struct InterpreterConfig {
1616
/// See [`with_type`](crate::Interpreter::with_type) for more details.
1717
pub types: Vec<(IdentQuadruple, MetaType)>,
1818

19+
/// List of types to be interpreted as dynamic types.
20+
///
21+
/// See [`with_dynamic_type`](crate::Interpreter::with_dynamic_type) for more details.
22+
pub dynamic_types: Vec<IdentQuadruple>,
23+
1924
/// Additional flags to control the interpreter.
2025
pub flags: InterpreterFlags,
2126

@@ -30,6 +35,7 @@ impl Default for InterpreterConfig {
3035
fn default() -> Self {
3136
Self {
3237
types: vec![],
38+
dynamic_types: vec![],
3339
debug_output: None,
3440
flags: InterpreterFlags::BUILDIN_TYPES
3541
| InterpreterFlags::DEFAULT_TYPEDEFS
@@ -43,6 +49,7 @@ impl Clone for InterpreterConfig {
4349
fn clone(&self) -> Self {
4450
Self {
4551
types: self.types.clone(),
52+
dynamic_types: self.dynamic_types.clone(),
4653
debug_output: self.debug_output.clone(),
4754
flags: self.flags.clone(),
4855
naming: self.naming.as_deref().map(Naming::clone_boxed),

xsd-parser/src/config/mod.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,33 @@ impl Config {
507507
self
508508
}
509509

510+
/// Add a list of types to be interpreted as dynamic types to the interpreter.
511+
///
512+
/// For details please refer to [`InterpreterConfig::dynamic_types`].
513+
pub fn with_dynamic_types<I>(mut self, types: I) -> Self
514+
where
515+
I: IntoIterator,
516+
I::Item: Into<IdentQuadruple>,
517+
{
518+
for ident in types {
519+
self.interpreter.dynamic_types.push(ident.into());
520+
}
521+
522+
self
523+
}
524+
525+
/// Add a type to be interpreted as a dynamic type to the interpreter.
526+
///
527+
/// For details please refer to [`InterpreterConfig::dynamic_types`].
528+
pub fn with_dynamic_type<T>(mut self, ident: T) -> Self
529+
where
530+
T: Into<IdentQuadruple>,
531+
{
532+
self.interpreter.dynamic_types.push(ident.into());
533+
534+
self
535+
}
536+
510537
/// Add a type to the interpreter that should be used to handle `xs:anySimpleType`.
511538
///
512539
/// This is a convenient method for adding support for `xs:anySimpleType` with a custom type.

xsd-parser/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ pub fn exec_interpreter_with_ident_cache(
230230
interpreter = interpreter.with_type(ident, ty)?;
231231
}
232232

233+
for ident in config.dynamic_types {
234+
let ident = ident.resolve(schemas)?;
235+
interpreter = interpreter.with_dynamic_type(ident);
236+
}
237+
233238
let (types, ident_cache) = interpreter.finish()?;
234239

235240
if let Some(output) = config.debug_output {
@@ -384,7 +389,11 @@ pub fn exec_generator_with_ident_cache<'types>(
384389
config.type_postfix.nillable_content,
385390
);
386391
generator = generator.with_type_postfix(
387-
IdentType::DynamicElement,
392+
IdentType::SubstitutionElement,
393+
config.type_postfix.dynamic_element.clone(),
394+
);
395+
generator = generator.with_type_postfix(
396+
IdentType::DynamicVariant,
388397
config.type_postfix.dynamic_element,
389398
);
390399

xsd-parser/src/meta_types_printer.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,11 @@ impl<'a> MetaTypesPrinter<'a> {
191191
.as_ref()
192192
.map_or_else(|| String::from("None"), ToString::to_string)
193193
);
194-
indentln!("derived_types:");
195194

195+
indentln!("derived_types:");
196196
s.level += 1;
197-
198-
for meta in &*x.derived_types {
199-
indentln!("{}", meta.type_);
197+
for (key, value) in &x.derived_types {
198+
indentln!("{key}={value:?}");
200199
}
201200

202201
s.level -= 2;

xsd-parser/src/models/ident.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ pub enum IdentType {
8585
NillableContent = 8,
8686

8787
/// One concrete element in a substitution group.
88-
DynamicElement = 9,
88+
SubstitutionElement = 9,
89+
90+
/// Represents a concrete type a dynamic type can have.
91+
DynamicVariant = 10,
8992
}
9093

9194
/* TypeIdent */
@@ -336,7 +339,8 @@ fn fmt_ident(
336339
Some(IdentType::AttributeGroup) => write!(f, "AttributeGroup(")?,
337340
Some(IdentType::Enumeration) => write!(f, "Enumeration(")?,
338341
Some(IdentType::NillableContent) => write!(f, "NillableContent(")?,
339-
Some(IdentType::DynamicElement) => write!(f, "DynamicElement(")?,
342+
Some(IdentType::SubstitutionElement) => write!(f, "SubstitutionElement(")?,
343+
Some(IdentType::DynamicVariant) => write!(f, "DynamicVariant(")?,
340344
}
341345

342346
if f.sign_minus() {

xsd-parser/src/models/meta/attribute.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ impl DerefMut for AttributesMeta {
192192

193193
impl TypeEq for AttributesMeta {
194194
fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
195-
TypeEq::type_hash_slice(&self.0, hasher, types);
195+
TypeEq::type_hash_iter(&self.0, hasher, types);
196196
}
197197

198198
fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {
Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,80 @@
1-
//! Contains the [`DynamicMeta`] type information and all related types.
1+
//! Contains the [`SubstitutionMeta`] type information and all related types.
22
33
use std::hash::{Hash, Hasher};
44

5+
use indexmap::IndexMap;
6+
57
use crate::models::TypeIdent;
68

79
use super::{MetaTypes, TypeEq};
810

9-
/// Type information that contains data about dynamic types.
11+
/// Type information that contains data about dynamic elements (substitution groups) or types.
1012
#[derive(Default, Debug, Clone)]
1113
pub struct DynamicMeta {
12-
/// Base type of the dynamic type.
14+
/// Base type of this dynamic type.
1315
pub type_: Option<TypeIdent>,
1416

15-
/// List of derived types.
16-
pub derived_types: Vec<DerivedTypeMeta>,
17-
}
17+
/// Whether the type was defined as abstract or not.
18+
pub is_abstract: bool,
1819

19-
/// Meta^ information about a derived type.
20-
#[derive(Debug, Clone)]
21-
pub struct DerivedTypeMeta {
22-
/// Identifier of the derived type.
23-
pub type_: TypeIdent,
24-
25-
/// Name of the element to use inside the generated code.
26-
pub display_name: Option<String>,
20+
/// Map of the derived types of this dynamic type.
21+
pub derived_types: IndexMap<TypeIdent, DerivedTypeMeta>,
2722
}
2823

2924
impl TypeEq for DynamicMeta {
3025
fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
3126
let Self {
3227
type_,
28+
is_abstract,
3329
derived_types,
3430
} = self;
3531

3632
type_.type_hash(hasher, types);
37-
TypeEq::type_hash_slice(derived_types, hasher, types);
33+
is_abstract.hash(hasher);
34+
TypeEq::type_hash_iter(derived_types, hasher, types);
3835
}
3936

4037
fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {
4138
let Self {
4239
type_,
40+
is_abstract,
4341
derived_types,
4442
} = self;
4543

4644
type_.type_eq(&other.type_, types)
45+
&& is_abstract == &other.is_abstract
4746
&& TypeEq::type_eq_iter(derived_types.iter(), other.derived_types.iter(), types)
4847
}
4948
}
5049

51-
impl DerivedTypeMeta {
52-
/// Creates a new [`DerivedTypeMeta`] instance with the given `type_`.
53-
#[must_use]
54-
pub fn new(type_: TypeIdent) -> Self {
55-
Self {
56-
type_,
57-
display_name: None,
58-
}
59-
}
50+
/// Meta information about a single derived type of a dynamic type.
51+
#[derive(Default, Debug, Clone)]
52+
pub struct DerivedTypeMeta {
53+
/// Is set to `true` if this derived type is directly defined in the dynamic type,
54+
/// otherwise it is inherited from another dynamic type.
55+
pub is_direct: bool,
56+
57+
/// Name of the element to use inside the generated code.
58+
pub display_name: Option<String>,
6059
}
6160

6261
impl TypeEq for DerivedTypeMeta {
63-
fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
62+
fn type_hash<H: Hasher>(&self, hasher: &mut H, _types: &MetaTypes) {
6463
let Self {
65-
type_,
6664
display_name,
65+
is_direct,
6766
} = self;
6867

69-
type_.type_hash(hasher, types);
7068
display_name.hash(hasher);
69+
is_direct.hash(hasher);
7170
}
7271

73-
fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {
72+
fn type_eq(&self, other: &Self, _types: &MetaTypes) -> bool {
7473
let Self {
75-
type_,
7674
display_name,
75+
is_direct,
7776
} = self;
7877

79-
type_.type_eq(&other.type_, types) && display_name == &other.display_name
78+
display_name == &other.display_name && is_direct == &other.is_direct
8079
}
8180
}

xsd-parser/src/models/meta/element.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ impl DerefMut for ElementsMeta {
258258

259259
impl TypeEq for ElementsMeta {
260260
fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
261-
TypeEq::type_hash_slice(&self.0, hasher, types);
261+
TypeEq::type_hash_iter(&self.0, hasher, types);
262262
}
263263

264264
fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {

xsd-parser/src/models/meta/enumeration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ impl DerefMut for EnumerationMetaVariants {
157157

158158
impl TypeEq for EnumerationMetaVariants {
159159
fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
160-
TypeEq::type_hash_slice(&self.0, hasher, types);
160+
TypeEq::type_hash_iter(&self.0, hasher, types);
161161
}
162162

163163
fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {

0 commit comments

Comments
 (0)