polyxml 0.33.4__tar.gz → 0.33.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {polyxml-0.33.4 → polyxml-0.33.6}/Cargo.lock +6 -6
- {polyxml-0.33.4 → polyxml-0.33.6}/Cargo.toml +1 -1
- {polyxml-0.33.4 → polyxml-0.33.6}/PKG-INFO +1 -1
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/csharp/mod.rs +63 -4
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/go/mod.rs +106 -18
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/java/codec.rs +1 -1
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/python/mod.rs +143 -6
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/rust/mod.rs +1 -1
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/ir/mod.rs +7 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/parser.rs +20 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/schema.rs +11 -1
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/schema_parser/mod.rs +181 -11
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_csharp_codegen.rs +149 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_go_codegen.rs +122 -4
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_python_codegen.rs +25 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_schema_ir.rs +37 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/src/lib.rs +21 -1
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/tests/test_generated_models.py +164 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/pyproject.toml +1 -1
- {polyxml-0.33.4 → polyxml-0.33.6}/README.md +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/Cargo.toml +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/README.md +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/benches/core_benchmarks.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/benches/support/tag_dispatch_fixtures.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/benches/tag_dispatch.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/cpp/mod.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/java/mod.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/java/models.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/mod.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/python/aot.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/codegen/typescript/mod.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/converters.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/error.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/ir/chunker.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/ir/tarjan.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/json.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/lib.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/serializer.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/transcoder.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/src/value.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/fixtures/lexical_union.xsd +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/fixtures/mixed_content.xsd +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/fixtures/ts_mixed_content_inheritance.xsd +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_adversarial_identifiers.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_any_attribute.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_any_element.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_conformance.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_core.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_cpp_codegen.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_java_codegen.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_json.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_lexical_union_codegen.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_mixed_content.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_pattern_codegen.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_rust_codecs.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_rust_codegen.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_schema_audit.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_security.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_transcoder.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_ts_codegen.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_unbounded_choice.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-core/tests/test_xsi_type.rs +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/Cargo.toml +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/README.md +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/benches/aot_vs_dataclass.py +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/tests/test_conformance.py +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/tests/test_json.py +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/tests/test_mixed_content.py +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/tests/test_polyxml.py +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/crates/polyxml-python/tests/test_xsi_type.py +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/python/polyxml/AGENT_GUIDE.md +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/python/polyxml/__init__.py +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/python/polyxml/compat/__init__.py +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/python/polyxml/compat/xsdata.py +0 -0
- {polyxml-0.33.4 → polyxml-0.33.6}/python/polyxml/py.typed +0 -0
|
@@ -608,7 +608,7 @@ dependencies = [
|
|
|
608
608
|
|
|
609
609
|
[[package]]
|
|
610
610
|
name = "polyxml"
|
|
611
|
-
version = "0.33.
|
|
611
|
+
version = "0.33.6"
|
|
612
612
|
dependencies = [
|
|
613
613
|
"criterion",
|
|
614
614
|
"heck",
|
|
@@ -629,14 +629,14 @@ dependencies = [
|
|
|
629
629
|
|
|
630
630
|
[[package]]
|
|
631
631
|
name = "polyxml-c"
|
|
632
|
-
version = "0.33.
|
|
632
|
+
version = "0.33.6"
|
|
633
633
|
dependencies = [
|
|
634
634
|
"polyxml",
|
|
635
635
|
]
|
|
636
636
|
|
|
637
637
|
[[package]]
|
|
638
638
|
name = "polyxml-cli"
|
|
639
|
-
version = "0.33.
|
|
639
|
+
version = "0.33.6"
|
|
640
640
|
dependencies = [
|
|
641
641
|
"clap",
|
|
642
642
|
"glob",
|
|
@@ -650,7 +650,7 @@ dependencies = [
|
|
|
650
650
|
|
|
651
651
|
[[package]]
|
|
652
652
|
name = "polyxml-js"
|
|
653
|
-
version = "0.33.
|
|
653
|
+
version = "0.33.6"
|
|
654
654
|
dependencies = [
|
|
655
655
|
"napi",
|
|
656
656
|
"napi-build",
|
|
@@ -660,7 +660,7 @@ dependencies = [
|
|
|
660
660
|
|
|
661
661
|
[[package]]
|
|
662
662
|
name = "polyxml-python"
|
|
663
|
-
version = "0.33.
|
|
663
|
+
version = "0.33.6"
|
|
664
664
|
dependencies = [
|
|
665
665
|
"lexical-core",
|
|
666
666
|
"polyxml",
|
|
@@ -670,7 +670,7 @@ dependencies = [
|
|
|
670
670
|
|
|
671
671
|
[[package]]
|
|
672
672
|
name = "polyxml-wasm"
|
|
673
|
-
version = "0.33.
|
|
673
|
+
version = "0.33.6"
|
|
674
674
|
dependencies = [
|
|
675
675
|
"polyxml",
|
|
676
676
|
"quick-xml",
|
|
@@ -273,6 +273,28 @@ fn simple_value_target(base: &TypeRef, ir: &SchemaIR) -> String {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
impl CSharpCodegen {
|
|
276
|
+
fn emit_optional_element_omission(
|
|
277
|
+
&self,
|
|
278
|
+
out: &mut String,
|
|
279
|
+
s: &StructDef,
|
|
280
|
+
names: &[String],
|
|
281
|
+
indent: &str,
|
|
282
|
+
) {
|
|
283
|
+
if self.options.emit_xml_attributes {
|
|
284
|
+
for (field, name) in s.fields.iter().zip(names) {
|
|
285
|
+
if field.kind == FieldKind::Element
|
|
286
|
+
&& field.cardinality.min_occurs == 0
|
|
287
|
+
&& !field.nillable
|
|
288
|
+
{
|
|
289
|
+
let _ = writeln!(
|
|
290
|
+
out,
|
|
291
|
+
"{indent} public bool ShouldSerialize{name}() => {name} is not null;"
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
276
298
|
/// Creates a new C# code generator with the given configuration options.
|
|
277
299
|
pub fn new(options: CSharpOptions) -> Self {
|
|
278
300
|
Self {
|
|
@@ -1002,7 +1024,7 @@ impl CSharpCodegen {
|
|
|
1002
1024
|
.map(|f| self.unique_property_name(&f.name, &mut seen_props, Some(&struct_name)))
|
|
1003
1025
|
.collect();
|
|
1004
1026
|
|
|
1005
|
-
if s
|
|
1027
|
+
if ir.has_ordered_content(s) && self.options.emit_xml_attributes {
|
|
1006
1028
|
self.emit_mixed_struct(out, s, ir, indent, &struct_name, &prop_names);
|
|
1007
1029
|
return;
|
|
1008
1030
|
}
|
|
@@ -1032,7 +1054,12 @@ impl CSharpCodegen {
|
|
|
1032
1054
|
"{} public {} {} {{ get; set; }} = default!;",
|
|
1033
1055
|
indent, ty, name
|
|
1034
1056
|
);
|
|
1035
|
-
let
|
|
1057
|
+
let xml_kind = if f.kind == FieldKind::Attribute {
|
|
1058
|
+
"XmlAttribute"
|
|
1059
|
+
} else {
|
|
1060
|
+
"XmlElement"
|
|
1061
|
+
};
|
|
1062
|
+
let _ = writeln!(out, "{} [{}({:?})]", indent, xml_kind, f.xml_name);
|
|
1036
1063
|
if self.options.emit_json_attributes {
|
|
1037
1064
|
let _ = writeln!(out, "{} [JsonIgnore]", indent);
|
|
1038
1065
|
}
|
|
@@ -1049,6 +1076,7 @@ impl CSharpCodegen {
|
|
|
1049
1076
|
indent, attrs, ty, name
|
|
1050
1077
|
);
|
|
1051
1078
|
}
|
|
1079
|
+
self.emit_optional_element_omission(out, s, &prop_names, indent);
|
|
1052
1080
|
if self.options.emit_validation {
|
|
1053
1081
|
self.emit_struct_validator(out, s, ir, &prop_names, indent);
|
|
1054
1082
|
}
|
|
@@ -1080,7 +1108,12 @@ impl CSharpCodegen {
|
|
|
1080
1108
|
"{} public {} {} {{ get; set; }} = default!;",
|
|
1081
1109
|
indent, ty, name
|
|
1082
1110
|
);
|
|
1083
|
-
let
|
|
1111
|
+
let xml_kind = if f.kind == FieldKind::Attribute {
|
|
1112
|
+
"XmlAttribute"
|
|
1113
|
+
} else {
|
|
1114
|
+
"XmlElement"
|
|
1115
|
+
};
|
|
1116
|
+
let _ = writeln!(out, "{} [{}({:?})]", indent, xml_kind, f.xml_name);
|
|
1084
1117
|
if self.options.emit_json_attributes {
|
|
1085
1118
|
let _ = writeln!(out, "{} [JsonIgnore]", indent);
|
|
1086
1119
|
}
|
|
@@ -1103,6 +1136,7 @@ impl CSharpCodegen {
|
|
|
1103
1136
|
)
|
|
1104
1137
|
.unwrap();
|
|
1105
1138
|
}
|
|
1139
|
+
self.emit_optional_element_omission(out, s, &prop_names, indent);
|
|
1106
1140
|
if self.options.emit_validation {
|
|
1107
1141
|
self.emit_struct_validator(out, s, ir, &prop_names, indent);
|
|
1108
1142
|
}
|
|
@@ -1191,6 +1225,8 @@ impl CSharpCodegen {
|
|
|
1191
1225
|
}
|
|
1192
1226
|
writeln!(out, ") {{ }}\n").unwrap();
|
|
1193
1227
|
|
|
1228
|
+
self.emit_optional_element_omission(out, s, &prop_names, indent);
|
|
1229
|
+
|
|
1194
1230
|
// IValidatableObject implementation
|
|
1195
1231
|
if self.options.emit_validation {
|
|
1196
1232
|
self.emit_struct_validator(out, s, ir, &prop_names, indent);
|
|
@@ -1379,6 +1415,11 @@ impl CSharpCodegen {
|
|
|
1379
1415
|
};
|
|
1380
1416
|
|
|
1381
1417
|
if f.cardinality.is_list() {
|
|
1418
|
+
let base_type = if f.nillable {
|
|
1419
|
+
format!("{}?", base_type)
|
|
1420
|
+
} else {
|
|
1421
|
+
base_type
|
|
1422
|
+
};
|
|
1382
1423
|
if f.cardinality.min_occurs == 0 || f.nillable {
|
|
1383
1424
|
format!("List<{}>?", base_type)
|
|
1384
1425
|
} else {
|
|
@@ -1422,7 +1463,14 @@ impl CSharpCodegen {
|
|
|
1422
1463
|
FieldKind::Text => parts.push("XmlText".to_string()),
|
|
1423
1464
|
FieldKind::Any => parts.push("XmlAnyElement".to_string()),
|
|
1424
1465
|
FieldKind::AnyAttribute => parts.push("XmlAnyAttribute".to_string()),
|
|
1425
|
-
FieldKind::Element =>
|
|
1466
|
+
FieldKind::Element => {
|
|
1467
|
+
let nullable = if f.nillable {
|
|
1468
|
+
", IsNullable = true"
|
|
1469
|
+
} else {
|
|
1470
|
+
""
|
|
1471
|
+
};
|
|
1472
|
+
parts.push(format!("XmlElement(\"{}\"{})", f.xml_name, nullable));
|
|
1473
|
+
}
|
|
1426
1474
|
}
|
|
1427
1475
|
}
|
|
1428
1476
|
}
|
|
@@ -1500,6 +1548,17 @@ impl CSharpCodegen {
|
|
|
1500
1548
|
continue;
|
|
1501
1549
|
}
|
|
1502
1550
|
}
|
|
1551
|
+
if self.options.use_records
|
|
1552
|
+
&& !matches!(&elem.type_ref, TypeRef::Named(q) if matches!(ir.types.get(q), Some(TypeDef::Struct(_) | TypeDef::Simple(_) | TypeDef::Union(_))))
|
|
1553
|
+
{
|
|
1554
|
+
let xml_attr = if self.options.emit_xml_attributes {
|
|
1555
|
+
"[property: XmlText] "
|
|
1556
|
+
} else {
|
|
1557
|
+
""
|
|
1558
|
+
};
|
|
1559
|
+
writeln!(out, "{}public sealed record {}({}{} Value)\n{}{{\n{} public {}() : this(default({})!) {{ }}\n{}}}\n", indent, elem_name, xml_attr, target_type, indent, indent, elem_name, target_type, indent).unwrap();
|
|
1560
|
+
continue;
|
|
1561
|
+
}
|
|
1503
1562
|
writeln!(
|
|
1504
1563
|
out,
|
|
1505
1564
|
"{}public sealed {} {} : {}\n{}{{",
|
|
@@ -119,7 +119,9 @@ impl LanguageContext for GoLanguageContext {
|
|
|
119
119
|
| PrimitiveType::GMonthDay
|
|
120
120
|
| PrimitiveType::GDay
|
|
121
121
|
| PrimitiveType::Duration => "string",
|
|
122
|
-
PrimitiveType::Date
|
|
122
|
+
PrimitiveType::Date => "PolyxmlDate",
|
|
123
|
+
PrimitiveType::Time => "PolyxmlTime",
|
|
124
|
+
PrimitiveType::DateTime => "PolyxmlDateTime",
|
|
123
125
|
PrimitiveType::Base64Binary | PrimitiveType::HexBinary => "[]byte",
|
|
124
126
|
PrimitiveType::AnyType | PrimitiveType::AnySimpleType => "any",
|
|
125
127
|
}
|
|
@@ -243,6 +245,46 @@ fn type_ident(q: &QName) -> String {
|
|
|
243
245
|
}
|
|
244
246
|
|
|
245
247
|
impl GoCodegen {
|
|
248
|
+
fn emit_temporal_types(&self, out: &mut String) {
|
|
249
|
+
for (name, layouts, default_layout) in [
|
|
250
|
+
(
|
|
251
|
+
"PolyxmlDate",
|
|
252
|
+
&["2006-01-02Z07:00", "2006-01-02"][..],
|
|
253
|
+
"2006-01-02Z07:00",
|
|
254
|
+
),
|
|
255
|
+
(
|
|
256
|
+
"PolyxmlTime",
|
|
257
|
+
&["15:04:05Z07:00", "15:04:05"][..],
|
|
258
|
+
"15:04:05.999999999Z07:00",
|
|
259
|
+
),
|
|
260
|
+
(
|
|
261
|
+
"PolyxmlDateTime",
|
|
262
|
+
&["2006-01-02T15:04:05Z07:00", "2006-01-02T15:04:05"][..],
|
|
263
|
+
"2006-01-02T15:04:05.999999999Z07:00",
|
|
264
|
+
),
|
|
265
|
+
] {
|
|
266
|
+
writeln!(out, "// {name} retains the XSD lexical form, including an absent timezone.\ntype {name} struct {{ time.Time; lexical string }}").unwrap();
|
|
267
|
+
writeln!(out, "func (v *{name}) UnmarshalText(text []byte) error {{\n value := strings.TrimSpace(string(text))").unwrap();
|
|
268
|
+
for layout in layouts {
|
|
269
|
+
writeln!(out, " if parsed, err := time.Parse({layout:?}, value); err == nil {{ *v = {name}{{Time: parsed, lexical: value}}; return nil }}").unwrap();
|
|
270
|
+
}
|
|
271
|
+
writeln!(out, " return fmt.Errorf(\"invalid {name}: %q\", value)\n}}\nfunc (v {name}) MarshalText() ([]byte, error) {{\n layout := {default_layout:?}").unwrap();
|
|
272
|
+
for original_layout in layouts {
|
|
273
|
+
writeln!(out, " if parsed, err := time.Parse({original_layout:?}, v.lexical); err == nil {{\n _, offset := v.Time.Zone(); _, originalOffset := parsed.Zone()\n if v.Time.Equal(parsed) && offset == originalOffset {{ return []byte(v.lexical), nil }}").unwrap();
|
|
274
|
+
if !original_layout.contains("Z07:00") {
|
|
275
|
+
writeln!(
|
|
276
|
+
out,
|
|
277
|
+
" layout = {:?}",
|
|
278
|
+
default_layout.trim_end_matches("Z07:00")
|
|
279
|
+
)
|
|
280
|
+
.unwrap();
|
|
281
|
+
}
|
|
282
|
+
out.push_str(" }\n");
|
|
283
|
+
}
|
|
284
|
+
out.push_str(" return []byte(v.Time.Format(layout)), nil\n}\n\n");
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
246
288
|
pub fn new(options: GoOptions) -> Self {
|
|
247
289
|
Self {
|
|
248
290
|
options,
|
|
@@ -278,7 +320,7 @@ impl GoCodegen {
|
|
|
278
320
|
for type_def in ir.emitted_types() {
|
|
279
321
|
match type_def {
|
|
280
322
|
TypeDef::Struct(s) => {
|
|
281
|
-
if s
|
|
323
|
+
if ir.has_ordered_content(s) && self.options.emit_xml_tags {
|
|
282
324
|
has_fmt = true;
|
|
283
325
|
has_io = true;
|
|
284
326
|
}
|
|
@@ -324,6 +366,9 @@ impl GoCodegen {
|
|
|
324
366
|
|
|
325
367
|
// Generate types
|
|
326
368
|
self.emit_types(&mut body, ir);
|
|
369
|
+
if has_time {
|
|
370
|
+
self.emit_temporal_types(&mut body);
|
|
371
|
+
}
|
|
327
372
|
self.emit_root_aliases(&mut body, ir);
|
|
328
373
|
|
|
329
374
|
// Assemble final output with package and imports
|
|
@@ -357,7 +402,7 @@ impl GoCodegen {
|
|
|
357
402
|
&& ir
|
|
358
403
|
.types
|
|
359
404
|
.values()
|
|
360
|
-
.any(|def| matches!(def, TypeDef::Struct(s) if s
|
|
405
|
+
.any(|def| matches!(def, TypeDef::Struct(s) if ir.has_ordered_content(s)))
|
|
361
406
|
{
|
|
362
407
|
imports.push("\"bytes\"");
|
|
363
408
|
}
|
|
@@ -466,6 +511,12 @@ impl GoCodegen {
|
|
|
466
511
|
let type_name = type_ident(&simple.qname);
|
|
467
512
|
let base_type = self.context.map_type_ref(&simple.base_type);
|
|
468
513
|
writeln!(out, "type {} {}\n", type_name, base_type).unwrap();
|
|
514
|
+
if matches!(
|
|
515
|
+
super::primitive_base(&simple.base_type, ir),
|
|
516
|
+
TypeRef::Primitive(PrimitiveType::Date | PrimitiveType::Time | PrimitiveType::DateTime)
|
|
517
|
+
) {
|
|
518
|
+
writeln!(out, "func (v *{type_name}) UnmarshalText(text []byte) error {{ return (*{base_type})(v).UnmarshalText(text) }}\nfunc (v {type_name}) MarshalText() ([]byte, error) {{ return {base_type}(v).MarshalText() }}\n").unwrap();
|
|
519
|
+
}
|
|
469
520
|
if self.options.validate_facets && !simple.facets.patterns.is_empty() {
|
|
470
521
|
writeln!(out, "func (s {}) Validate() error {{", type_name).unwrap();
|
|
471
522
|
for pattern in &simple.facets.patterns {
|
|
@@ -771,7 +822,13 @@ impl GoCodegen {
|
|
|
771
822
|
"func (c *{}) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {{",
|
|
772
823
|
name
|
|
773
824
|
);
|
|
774
|
-
out.push_str(" var raw string\n if err := d.DecodeElement(&raw, &start); err != nil { return err }\n
|
|
825
|
+
out.push_str(" var raw string\n if err := d.DecodeElement(&raw, &start); err != nil { return err }\n return c.UnmarshalText([]byte(raw))\n}\n\n");
|
|
826
|
+
let _ = writeln!(
|
|
827
|
+
out,
|
|
828
|
+
"func (c *{}) UnmarshalText(text []byte) error {{",
|
|
829
|
+
name
|
|
830
|
+
);
|
|
831
|
+
out.push_str(" value := strings.TrimSpace(string(text))\n *c = ");
|
|
775
832
|
let _ = writeln!(out, "{}{{}}", name);
|
|
776
833
|
for (branch, field) in u.branches.iter().zip(&fields) {
|
|
777
834
|
let mapped = self.context.map_type_ref(&branch.type_ref);
|
|
@@ -819,13 +876,13 @@ impl GoCodegen {
|
|
|
819
876
|
_ => None,
|
|
820
877
|
};
|
|
821
878
|
if matches!(base, TypeRef::Primitive(PrimitiveType::Date)) {
|
|
822
|
-
let _ = writeln!(out, " if parsed, err := time.Parse(\"2006-01-02\", value); err == nil {{ v := {}
|
|
879
|
+
let _ = writeln!(out, " if parsed, err := time.Parse(\"2006-01-02\", value); err == nil {{ v := {}{{Time: parsed, lexical: value}}; c.{} = &v; return nil }}", mapped, field);
|
|
823
880
|
} else if matches!(base, TypeRef::Primitive(PrimitiveType::DateTime)) {
|
|
824
|
-
let _ = writeln!(out, " if parsed, err := time.Parse(time.RFC3339, value); err == nil {{ v := {}
|
|
825
|
-
let _ = writeln!(out, " if parsed, err := time.Parse(\"2006-01-02T15:04:05\", value); err == nil {{ v := {}
|
|
881
|
+
let _ = writeln!(out, " if parsed, err := time.Parse(time.RFC3339, value); err == nil {{ v := {}{{Time: parsed, lexical: value}}; c.{} = &v; return nil }}", mapped, field);
|
|
882
|
+
let _ = writeln!(out, " if parsed, err := time.Parse(\"2006-01-02T15:04:05\", value); err == nil {{ v := {}{{Time: parsed, lexical: value}}; c.{} = &v; return nil }}", mapped, field);
|
|
826
883
|
} else if matches!(base, TypeRef::Primitive(PrimitiveType::Time)) {
|
|
827
|
-
let _ = writeln!(out, " if parsed, err := time.Parse(\"15:04:05Z07:00\", value); err == nil {{ v := {}
|
|
828
|
-
let _ = writeln!(out, " if parsed, err := time.Parse(\"15:04:05\", value); err == nil {{ v := {}
|
|
884
|
+
let _ = writeln!(out, " if parsed, err := time.Parse(\"15:04:05Z07:00\", value); err == nil {{ v := {}{{Time: parsed, lexical: value}}; c.{} = &v; return nil }}", mapped, field);
|
|
885
|
+
let _ = writeln!(out, " if parsed, err := time.Parse(\"15:04:05\", value); err == nil {{ v := {}{{Time: parsed, lexical: value}}; c.{} = &v; return nil }}", mapped, field);
|
|
829
886
|
} else if let Some(kind) = numeric {
|
|
830
887
|
let parse = match kind {
|
|
831
888
|
"signed" => "strconv.ParseInt(value, 10, 64)",
|
|
@@ -881,11 +938,22 @@ impl GoCodegen {
|
|
|
881
938
|
"func (c {}) MarshalXML(e *xml.Encoder, start xml.StartElement) error {{",
|
|
882
939
|
name
|
|
883
940
|
);
|
|
941
|
+
out.push_str(" text, err := c.MarshalText()\n if err != nil { return err }\n return e.EncodeElement(string(text), start)\n}\n\n");
|
|
942
|
+
let _ = writeln!(out, "func (c {}) MarshalText() ([]byte, error) {{", name);
|
|
884
943
|
out.push_str(" count := 0\n var value string\n");
|
|
885
944
|
for (branch, field) in u.branches.iter().zip(&fields) {
|
|
886
945
|
if matches!(&branch.type_ref, TypeRef::Named(qname) if matches!(ir.types.get(qname), Some(TypeDef::Union(inner)) if inner.is_lexical()))
|
|
887
946
|
{
|
|
888
|
-
let _ = writeln!(out, " if c.{field} != nil {{ data, err := xml.Marshal(c.{field}); if err != nil {{ return err }}; if err := xml.Unmarshal(data, &value); err != nil {{ return err }}; count++ }}");
|
|
947
|
+
let _ = writeln!(out, " if c.{field} != nil {{ data, err := xml.Marshal(c.{field}); if err != nil {{ return nil, err }}; if err := xml.Unmarshal(data, &value); err != nil {{ return nil, err }}; count++ }}");
|
|
948
|
+
continue;
|
|
949
|
+
}
|
|
950
|
+
if matches!(
|
|
951
|
+
super::primitive_base(&branch.type_ref, ir),
|
|
952
|
+
TypeRef::Primitive(
|
|
953
|
+
PrimitiveType::Date | PrimitiveType::Time | PrimitiveType::DateTime
|
|
954
|
+
)
|
|
955
|
+
) {
|
|
956
|
+
let _ = writeln!(out, " if c.{field} != nil {{ text, err := c.{field}.MarshalText(); if err != nil {{ return nil, err }}; count++; value = string(text) }}");
|
|
889
957
|
continue;
|
|
890
958
|
}
|
|
891
959
|
let expr = if matches!(
|
|
@@ -912,7 +980,7 @@ impl GoCodegen {
|
|
|
912
980
|
field, expr
|
|
913
981
|
);
|
|
914
982
|
}
|
|
915
|
-
out.push_str(" if count != 1 { return fmt.Errorf(\"lexical union requires exactly one member\") }\n return
|
|
983
|
+
out.push_str(" if count != 1 { return nil, fmt.Errorf(\"lexical union requires exactly one member\") }\n return []byte(value), nil\n}\n\n");
|
|
916
984
|
}
|
|
917
985
|
|
|
918
986
|
fn emit_struct(&self, out: &mut String, s: &StructDef, ir: &SchemaIR) {
|
|
@@ -1036,7 +1104,7 @@ impl GoCodegen {
|
|
|
1036
1104
|
|
|
1037
1105
|
writeln!(out, "}}\n").unwrap();
|
|
1038
1106
|
|
|
1039
|
-
if s
|
|
1107
|
+
if ir.has_ordered_content(s) && self.options.emit_xml_tags {
|
|
1040
1108
|
self.emit_mixed_struct_xml(out, s, ir, &field_names);
|
|
1041
1109
|
}
|
|
1042
1110
|
|
|
@@ -1162,7 +1230,9 @@ impl GoCodegen {
|
|
|
1162
1230
|
let xml_val = match f.kind {
|
|
1163
1231
|
FieldKind::Attribute => {
|
|
1164
1232
|
let attr_name = match &f.namespace {
|
|
1165
|
-
Some(ns) if !ns.is_empty()
|
|
1233
|
+
Some(ns) if !ns.is_empty() && is_namespaced_ref(f, s, ir) => {
|
|
1234
|
+
format!("{} {}", ns, f.xml_name)
|
|
1235
|
+
}
|
|
1166
1236
|
_ => f.xml_name.clone(),
|
|
1167
1237
|
};
|
|
1168
1238
|
if is_opt {
|
|
@@ -1175,10 +1245,11 @@ impl GoCodegen {
|
|
|
1175
1245
|
FieldKind::Any => ",any".to_string(),
|
|
1176
1246
|
FieldKind::AnyAttribute => ",any,attr".to_string(),
|
|
1177
1247
|
FieldKind::Element => {
|
|
1178
|
-
let elem_name =
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1248
|
+
let elem_name = match &f.namespace {
|
|
1249
|
+
Some(ns) if !ns.is_empty() && is_namespaced_ref(f, s, ir) => {
|
|
1250
|
+
format!("{} {}", ns, f.xml_name)
|
|
1251
|
+
}
|
|
1252
|
+
_ => f.xml_name.clone(),
|
|
1182
1253
|
};
|
|
1183
1254
|
if f.xml_name.is_empty() {
|
|
1184
1255
|
",any".to_string()
|
|
@@ -1630,7 +1701,24 @@ impl GoCodegen {
|
|
|
1630
1701
|
}
|
|
1631
1702
|
}
|
|
1632
1703
|
}
|
|
1633
|
-
|
|
1704
|
+
if self.options.emit_xml_tags {
|
|
1705
|
+
let namespace = elem.qname.namespace.as_deref().unwrap_or("");
|
|
1706
|
+
writeln!(out, "type {} {}\n", elem_alias, target_type).unwrap();
|
|
1707
|
+
if matches!(&elem.type_ref, TypeRef::Named(q) if matches!(ir.types.get(q), Some(TypeDef::Struct(s)) if s.is_abstract))
|
|
1708
|
+
{
|
|
1709
|
+
writeln!(out, "func (r {elem_alias}) Selected() string {{ return {target_type}(r).Selected() }}\n").unwrap();
|
|
1710
|
+
}
|
|
1711
|
+
writeln!(out, "func (r *{elem_alias}) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {{\n if start.Name.Local != {:?} || start.Name.Space != {:?} {{ return fmt.Errorf(\"unexpected root element: %v\", start.Name) }}\n return d.DecodeElement((*{target_type})(r), &start)\n}}\n", elem.qname.local, namespace).unwrap();
|
|
1712
|
+
let bind_name = if matches!(&elem.type_ref, TypeRef::Named(q) if matches!(ir.types.get(q), Some(TypeDef::Struct(_))))
|
|
1713
|
+
{
|
|
1714
|
+
" value.XMLName = start.Name\n"
|
|
1715
|
+
} else {
|
|
1716
|
+
""
|
|
1717
|
+
};
|
|
1718
|
+
writeln!(out, "func (r {elem_alias}) MarshalXML(e *xml.Encoder, start xml.StartElement) error {{\n start.Name = xml.Name{{Local: {:?}, Space: {:?}}}\n value := {target_type}(r)\n{bind_name} return e.EncodeElement(value, start)\n}}\n", elem.qname.local, namespace).unwrap();
|
|
1719
|
+
} else {
|
|
1720
|
+
writeln!(out, "type {} = {}\n", elem_alias, target_type).unwrap();
|
|
1721
|
+
}
|
|
1634
1722
|
}
|
|
1635
1723
|
}
|
|
1636
1724
|
}
|
|
@@ -298,7 +298,7 @@ impl JavaCodegen {
|
|
|
298
298
|
if text_field.is_some() {
|
|
299
299
|
out.push_str(" if (event == XMLStreamConstants.CHARACTERS || event == XMLStreamConstants.CDATA) text.append(reader.getText());\n");
|
|
300
300
|
}
|
|
301
|
-
if s
|
|
301
|
+
if ir.has_ordered_content(s) {
|
|
302
302
|
if let Some((field, id, union)) = fields.iter().find_map(|(field, id)| {
|
|
303
303
|
self.resolve_union_def(&field.type_ref, ir)
|
|
304
304
|
.filter(|union| union.is_mixed_content())
|
|
@@ -305,7 +305,7 @@ impl PythonCodegen {
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
fn emit_imports(&self, out: &mut String, ir: &SchemaIR) {
|
|
308
|
-
let mut has_structs =
|
|
308
|
+
let mut has_structs = self.options.emit_root_aliases && !ir.elements.is_empty();
|
|
309
309
|
let mut has_enums = false;
|
|
310
310
|
let mut has_decimal = false;
|
|
311
311
|
let mut has_annotated = false;
|
|
@@ -634,7 +634,7 @@ impl PythonCodegen {
|
|
|
634
634
|
has_body = true;
|
|
635
635
|
}
|
|
636
636
|
|
|
637
|
-
if self.options.emit_meta || s
|
|
637
|
+
if self.options.emit_meta || ir.has_ordered_content(s) {
|
|
638
638
|
if has_body {
|
|
639
639
|
out.push('\n');
|
|
640
640
|
}
|
|
@@ -644,6 +644,7 @@ impl PythonCodegen {
|
|
|
644
644
|
out.push_str(" class Meta:\n");
|
|
645
645
|
}
|
|
646
646
|
let _ = writeln!(out, " name = \"{}\"", s.qname.local);
|
|
647
|
+
out.push_str(" strict_root = False\n");
|
|
647
648
|
if let Some(ref ns) = s.qname.namespace {
|
|
648
649
|
let _ = writeln!(out, " namespace = \"{}\"", ns);
|
|
649
650
|
}
|
|
@@ -652,8 +653,10 @@ impl PythonCodegen {
|
|
|
652
653
|
// derivations.
|
|
653
654
|
if s.is_abstract {
|
|
654
655
|
out.push_str(" abstract = True\n");
|
|
656
|
+
} else if struct_base.is_some() {
|
|
657
|
+
out.push_str(" abstract = False\n");
|
|
655
658
|
}
|
|
656
|
-
if s
|
|
659
|
+
if ir.has_ordered_content(s) {
|
|
657
660
|
if let Some(item_field) = s
|
|
658
661
|
.fields
|
|
659
662
|
.iter()
|
|
@@ -722,7 +725,28 @@ impl PythonCodegen {
|
|
|
722
725
|
out.push_str(" ) -> bytes:\n");
|
|
723
726
|
out.push_str(" \"\"\"Serialize this model instance into XML bytes.\"\"\"\n");
|
|
724
727
|
out.push_str(" import polyxml\n");
|
|
725
|
-
|
|
728
|
+
let mut ancestors = BTreeSet::new();
|
|
729
|
+
let mut base = s.base_type.as_ref();
|
|
730
|
+
while let Some(q) = base {
|
|
731
|
+
if !ancestors.insert(q.clone()) {
|
|
732
|
+
break;
|
|
733
|
+
}
|
|
734
|
+
base = match ir.types.get(q) {
|
|
735
|
+
Some(TypeDef::Struct(parent)) => parent.base_type.as_ref(),
|
|
736
|
+
_ => None,
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
let roots = ir.elements.values().filter(|element| matches!(&element.type_ref, TypeRef::Named(q) if ancestors.contains(q) && matches!(ir.types.get(q), Some(TypeDef::Struct(parent)) if parent.is_abstract))).collect::<Vec<_>>();
|
|
740
|
+
if let [root] = roots.as_slice() {
|
|
741
|
+
let root_name = AsPascalCase(&root.qname.local).to_string();
|
|
742
|
+
if !ir.types.keys().any(|q| type_ident(q) == root_name) {
|
|
743
|
+
let _ = writeln!(out, " return polyxml.serialize(self, target_type={}, indent=indent, namespaces=namespaces, ns_map=ns_map)\n", root_name);
|
|
744
|
+
} else {
|
|
745
|
+
out.push_str(" return polyxml.serialize(self, indent=indent, namespaces=namespaces, ns_map=ns_map)\n\n");
|
|
746
|
+
}
|
|
747
|
+
} else {
|
|
748
|
+
out.push_str(" return polyxml.serialize(self, indent=indent, namespaces=namespaces, ns_map=ns_map)\n\n");
|
|
749
|
+
}
|
|
726
750
|
out.push_str(" @classmethod\n");
|
|
727
751
|
out.push_str(" def from_json(cls, data: bytes | str) -> Self:\n");
|
|
728
752
|
out.push_str(" \"\"\"Deserialize JSON bytes or string into this model.\"\"\"\n");
|
|
@@ -1077,11 +1101,124 @@ impl PythonCodegen {
|
|
|
1077
1101
|
}
|
|
1078
1102
|
|
|
1079
1103
|
for element in ir.elements.values() {
|
|
1080
|
-
let el_name = AsPascalCase(&element.qname.local).to_string();
|
|
1104
|
+
let mut el_name = AsPascalCase(&element.qname.local).to_string();
|
|
1105
|
+
let root_count = ir
|
|
1106
|
+
.elements
|
|
1107
|
+
.values()
|
|
1108
|
+
.filter(|other| AsPascalCase(&other.qname.local).to_string() == el_name)
|
|
1109
|
+
.count();
|
|
1110
|
+
if root_count == 1
|
|
1111
|
+
&& declared_names.contains(&el_name)
|
|
1112
|
+
&& self.options.emit_meta
|
|
1113
|
+
&& matches!(&element.type_ref, TypeRef::Named(q) if q == &element.qname && type_ident(q) == el_name && matches!(ir.types.get(q), Some(TypeDef::Struct(_))))
|
|
1114
|
+
{
|
|
1115
|
+
let _ = writeln!(
|
|
1116
|
+
out,
|
|
1117
|
+
"\n{}.Meta.strict_root = True\n{}.Meta.name = {:?}",
|
|
1118
|
+
el_name, el_name, element.qname.local
|
|
1119
|
+
);
|
|
1120
|
+
continue;
|
|
1121
|
+
}
|
|
1122
|
+
if declared_names.contains(&el_name) {
|
|
1123
|
+
let base = format!("{}Element", el_name);
|
|
1124
|
+
el_name = base.clone();
|
|
1125
|
+
let mut suffix = 2;
|
|
1126
|
+
while declared_names.contains(&el_name) {
|
|
1127
|
+
el_name = format!("{base}{suffix}");
|
|
1128
|
+
suffix += 1;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1081
1131
|
if !declared_names.contains(&el_name) {
|
|
1082
1132
|
let target_type = self.context.map_type_ref(&element.type_ref);
|
|
1083
1133
|
if el_name != target_type {
|
|
1084
|
-
|
|
1134
|
+
if matches!(&element.type_ref, TypeRef::Named(q) if matches!(ir.types.get(q), Some(TypeDef::Struct(_))))
|
|
1135
|
+
{
|
|
1136
|
+
if self.options.backend != PythonBackend::Pydantic {
|
|
1137
|
+
let _ = writeln!(
|
|
1138
|
+
out,
|
|
1139
|
+
"\n@dataclass(slots={}, kw_only={})",
|
|
1140
|
+
if self.options.slots { "True" } else { "False" },
|
|
1141
|
+
if self.options.kw_only {
|
|
1142
|
+
"True"
|
|
1143
|
+
} else {
|
|
1144
|
+
"False"
|
|
1145
|
+
}
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
let meta_base = if self.options.emit_meta {
|
|
1149
|
+
format!("({}.Meta)", target_type)
|
|
1150
|
+
} else {
|
|
1151
|
+
String::new()
|
|
1152
|
+
};
|
|
1153
|
+
let _ = writeln!(out, "class {}({}):\n class Meta{}:\n name = {:?}\n namespace = {:?}\n strict_root = True", el_name, target_type, meta_base, element.qname.local, element.qname.namespace.as_deref().unwrap_or(""));
|
|
1154
|
+
let _ = writeln!(out, " root_type = {}", target_type);
|
|
1155
|
+
} else {
|
|
1156
|
+
let fields = if let TypeRef::Named(q) = &element.type_ref {
|
|
1157
|
+
if let Some(TypeDef::Union(union)) = ir
|
|
1158
|
+
.types
|
|
1159
|
+
.get(q)
|
|
1160
|
+
.filter(|t| matches!(t, TypeDef::Union(u) if !u.is_lexical()))
|
|
1161
|
+
{
|
|
1162
|
+
union
|
|
1163
|
+
.branches
|
|
1164
|
+
.iter()
|
|
1165
|
+
.map(|branch| {
|
|
1166
|
+
let mut field = FieldDef::new(
|
|
1167
|
+
&branch.variant_name,
|
|
1168
|
+
&branch.xml_name,
|
|
1169
|
+
FieldKind::Element,
|
|
1170
|
+
branch.type_ref.clone(),
|
|
1171
|
+
);
|
|
1172
|
+
field.namespace = branch.namespace.clone();
|
|
1173
|
+
field.cardinality = crate::ir::Cardinality::optional_one();
|
|
1174
|
+
field
|
|
1175
|
+
})
|
|
1176
|
+
.collect()
|
|
1177
|
+
} else {
|
|
1178
|
+
vec![FieldDef::new(
|
|
1179
|
+
"value",
|
|
1180
|
+
"",
|
|
1181
|
+
FieldKind::Text,
|
|
1182
|
+
element.type_ref.clone(),
|
|
1183
|
+
)]
|
|
1184
|
+
}
|
|
1185
|
+
} else {
|
|
1186
|
+
let mut value = FieldDef::new(
|
|
1187
|
+
"value",
|
|
1188
|
+
"",
|
|
1189
|
+
FieldKind::Text,
|
|
1190
|
+
element.type_ref.clone(),
|
|
1191
|
+
);
|
|
1192
|
+
if matches!(
|
|
1193
|
+
element.type_ref,
|
|
1194
|
+
TypeRef::Primitive(
|
|
1195
|
+
PrimitiveType::AnyType | PrimitiveType::AnySimpleType
|
|
1196
|
+
)
|
|
1197
|
+
) {
|
|
1198
|
+
value.cardinality = crate::ir::Cardinality::optional_one();
|
|
1199
|
+
} else if matches!(
|
|
1200
|
+
element.type_ref,
|
|
1201
|
+
TypeRef::Primitive(PrimitiveType::String)
|
|
1202
|
+
) {
|
|
1203
|
+
value.default_value = Some(String::new());
|
|
1204
|
+
}
|
|
1205
|
+
vec![value]
|
|
1206
|
+
};
|
|
1207
|
+
let wrapper = StructDef {
|
|
1208
|
+
qname: QName::new(element.qname.namespace.clone(), &el_name),
|
|
1209
|
+
base_type: None,
|
|
1210
|
+
is_abstract: false,
|
|
1211
|
+
is_mixed: false,
|
|
1212
|
+
fields,
|
|
1213
|
+
documentation: element.documentation.clone(),
|
|
1214
|
+
};
|
|
1215
|
+
self.emit_struct(out, &wrapper, ir);
|
|
1216
|
+
let _ = writeln!(
|
|
1217
|
+
out,
|
|
1218
|
+
"{}.Meta.strict_root = True\n{}.Meta.name = {:?}",
|
|
1219
|
+
el_name, el_name, element.qname.local
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1085
1222
|
declared_names.insert(el_name);
|
|
1086
1223
|
}
|
|
1087
1224
|
}
|
|
@@ -1630,7 +1630,7 @@ impl RustCodegen {
|
|
|
1630
1630
|
out.push_str(" },\n");
|
|
1631
1631
|
|
|
1632
1632
|
out.push_str(" Event::End(e) if e.local_name().as_ref() == start.local_name().as_ref() => break,\n");
|
|
1633
|
-
if s
|
|
1633
|
+
if ir.has_ordered_content(s) {
|
|
1634
1634
|
let item_union = field_metas.iter().find_map(|meta| {
|
|
1635
1635
|
self.resolve_union_def(&meta.field.type_ref, ir)
|
|
1636
1636
|
.filter(|u| u.is_mixed_content())
|