polyxml 0.34.8__tar.gz → 0.35.0__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.34.8 → polyxml-0.35.0}/Cargo.lock +18 -18
- {polyxml-0.34.8 → polyxml-0.35.0}/Cargo.toml +1 -1
- {polyxml-0.34.8 → polyxml-0.35.0}/PKG-INFO +1 -1
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/rust/mod.rs +147 -1
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/schema.rs +38 -8
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/schema_parser/upa.rs +66 -19
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_rust_codegen.rs +49 -0
- polyxml-0.35.0/crates/polyxml-core/tests/test_variant_registry.rs +75 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/pyproject.toml +1 -1
- {polyxml-0.34.8 → polyxml-0.35.0}/README.md +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/Cargo.toml +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/README.md +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/benches/core_benchmarks.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/benches/support/tag_dispatch_fixtures.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/benches/tag_dispatch.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/cpp/mod.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/csharp/mod.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/go/mod.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/java/codec.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/java/mod.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/java/models.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/mod.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/python/aot.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/python/mod.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/codegen/typescript/mod.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/converters.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/error.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/integer.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/ir/chunker.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/ir/mod.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/ir/particle.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/ir/tarjan.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/json.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/lib.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/parser.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/pattern.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/schema_parser/mod.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/serializer.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/transcoder.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/src/value.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/fixtures/lexical_union.xsd +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/fixtures/mixed_content.xsd +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/fixtures/ts_mixed_content_inheritance.xsd +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_adversarial_identifiers.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_any_attribute.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_any_element.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_conformance.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_core.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_cpp_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_csharp_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_default_literal_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_enum_literal_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_go_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_inherited_simple_content.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_inherited_text_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_java_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_json.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_lexical_lists.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_lexical_union_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_mixed_branch_lookup.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_mixed_content.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_mixed_nil.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_namespace_entities.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_pattern_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_python_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_qualified_attributes.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_runtime_fast_paths.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_rust_codecs.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_schema_attribute_entities.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_schema_audit.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_schema_ir.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_security.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_temporal_union.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_transcoder.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_ts_codegen.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_ubl_csharp.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_unbounded_choice.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_upa.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_value_constraints.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_xsi_type.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/Cargo.toml +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/README.md +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/benches/aot_vs_dataclass.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/src/lib.rs +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/tests/test_conformance.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/tests/test_generated_models.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/tests/test_json.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/tests/test_mixed_content.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/tests/test_polyxml.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-python/tests/test_xsi_type.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/python/polyxml/AGENT_GUIDE.md +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/python/polyxml/__init__.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/python/polyxml/compat/__init__.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/python/polyxml/compat/xsdata.py +0 -0
- {polyxml-0.34.8 → polyxml-0.35.0}/python/polyxml/py.typed +0 -0
|
@@ -474,9 +474,9 @@ dependencies = [
|
|
|
474
474
|
|
|
475
475
|
[[package]]
|
|
476
476
|
name = "napi-build"
|
|
477
|
-
version = "2.
|
|
477
|
+
version = "2.6.0"
|
|
478
478
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
479
|
-
checksum = "
|
|
479
|
+
checksum = "b899b545d3aa6dca985939059f258c5488d34e4ecf39c274e20009748f4b846d"
|
|
480
480
|
|
|
481
481
|
[[package]]
|
|
482
482
|
name = "napi-derive"
|
|
@@ -608,7 +608,7 @@ dependencies = [
|
|
|
608
608
|
|
|
609
609
|
[[package]]
|
|
610
610
|
name = "polyxml"
|
|
611
|
-
version = "0.
|
|
611
|
+
version = "0.35.0"
|
|
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.
|
|
632
|
+
version = "0.35.0"
|
|
633
633
|
dependencies = [
|
|
634
634
|
"polyxml",
|
|
635
635
|
]
|
|
636
636
|
|
|
637
637
|
[[package]]
|
|
638
638
|
name = "polyxml-cli"
|
|
639
|
-
version = "0.
|
|
639
|
+
version = "0.35.0"
|
|
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.
|
|
653
|
+
version = "0.35.0"
|
|
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.
|
|
663
|
+
version = "0.35.0"
|
|
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.
|
|
673
|
+
version = "0.35.0"
|
|
674
674
|
dependencies = [
|
|
675
675
|
"polyxml",
|
|
676
676
|
"quick-xml",
|
|
@@ -704,9 +704,9 @@ dependencies = [
|
|
|
704
704
|
|
|
705
705
|
[[package]]
|
|
706
706
|
name = "pyo3"
|
|
707
|
-
version = "0.29.
|
|
707
|
+
version = "0.29.3"
|
|
708
708
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
709
|
-
checksum = "
|
|
709
|
+
checksum = "700d18fa267b73b9b521fd7e13580e2f446916f176cacee1ab63fcc8191f1655"
|
|
710
710
|
dependencies = [
|
|
711
711
|
"libc",
|
|
712
712
|
"once_cell",
|
|
@@ -718,18 +718,18 @@ dependencies = [
|
|
|
718
718
|
|
|
719
719
|
[[package]]
|
|
720
720
|
name = "pyo3-build-config"
|
|
721
|
-
version = "0.29.
|
|
721
|
+
version = "0.29.3"
|
|
722
722
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
723
|
-
checksum = "
|
|
723
|
+
checksum = "7b3fc0c4d08f6bb10e71fe39dfb9e2f59c6eb6854e22ec8092f50c69a4499adb"
|
|
724
724
|
dependencies = [
|
|
725
725
|
"target-lexicon",
|
|
726
726
|
]
|
|
727
727
|
|
|
728
728
|
[[package]]
|
|
729
729
|
name = "pyo3-ffi"
|
|
730
|
-
version = "0.29.
|
|
730
|
+
version = "0.29.3"
|
|
731
731
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
732
|
-
checksum = "
|
|
732
|
+
checksum = "dfc0b8e19df29aad7086cf977bb0c2a2f143e30567eb113e9cf72b62ca698330"
|
|
733
733
|
dependencies = [
|
|
734
734
|
"libc",
|
|
735
735
|
"pyo3-build-config",
|
|
@@ -737,9 +737,9 @@ dependencies = [
|
|
|
737
737
|
|
|
738
738
|
[[package]]
|
|
739
739
|
name = "pyo3-macros"
|
|
740
|
-
version = "0.29.
|
|
740
|
+
version = "0.29.3"
|
|
741
741
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
742
|
-
checksum = "
|
|
742
|
+
checksum = "6100e8a4b5eba53afaa5ed078364851a0b2499c553a44c31026b929049b49dc6"
|
|
743
743
|
dependencies = [
|
|
744
744
|
"proc-macro2",
|
|
745
745
|
"pyo3-macros-backend",
|
|
@@ -749,9 +749,9 @@ dependencies = [
|
|
|
749
749
|
|
|
750
750
|
[[package]]
|
|
751
751
|
name = "pyo3-macros-backend"
|
|
752
|
-
version = "0.29.
|
|
752
|
+
version = "0.29.3"
|
|
753
753
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
754
|
-
checksum = "
|
|
754
|
+
checksum = "6143877a16e82b5a727b7127ff4cd86858a24a28d745d72f43e6f227c7b1bdb3"
|
|
755
755
|
dependencies = [
|
|
756
756
|
"heck",
|
|
757
757
|
"proc-macro2",
|
|
@@ -1940,6 +1940,136 @@ impl RustCodegen {
|
|
|
1940
1940
|
out.push_str(" }\n");
|
|
1941
1941
|
|
|
1942
1942
|
out.push_str("}\n");
|
|
1943
|
+
self.emit_incremental_roots(out, s, ir, types_with_lifetime);
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
/// Only expose the producer API where ordinary item codecs preserve the schema.
|
|
1947
|
+
fn emit_incremental_roots(
|
|
1948
|
+
&self,
|
|
1949
|
+
out: &mut String,
|
|
1950
|
+
s: &StructDef,
|
|
1951
|
+
ir: &SchemaIR,
|
|
1952
|
+
lifetimes: &HashSet<QName>,
|
|
1953
|
+
) {
|
|
1954
|
+
fn supported(
|
|
1955
|
+
s: &StructDef,
|
|
1956
|
+
ir: &SchemaIR,
|
|
1957
|
+
namespace: &Option<String>,
|
|
1958
|
+
seen: &mut HashSet<QName>,
|
|
1959
|
+
) -> bool {
|
|
1960
|
+
if ir
|
|
1961
|
+
.upa_documents
|
|
1962
|
+
.iter()
|
|
1963
|
+
.find_map(|doc| doc.uniform_sequence(&s.qname, namespace))
|
|
1964
|
+
!= Some(true)
|
|
1965
|
+
{
|
|
1966
|
+
return false;
|
|
1967
|
+
}
|
|
1968
|
+
if !seen.insert(s.qname.clone()) {
|
|
1969
|
+
return false;
|
|
1970
|
+
}
|
|
1971
|
+
if s.base_type.is_some()
|
|
1972
|
+
|| s.is_abstract
|
|
1973
|
+
|| s.is_mixed
|
|
1974
|
+
|| ir.ordered_types.contains(&s.qname)
|
|
1975
|
+
{
|
|
1976
|
+
return false;
|
|
1977
|
+
}
|
|
1978
|
+
if ir
|
|
1979
|
+
.content_models
|
|
1980
|
+
.get(&s.qname)
|
|
1981
|
+
.is_some_and(|p| p.has_choice() || p.has_reference() || p.has_repeated_sequence())
|
|
1982
|
+
{
|
|
1983
|
+
return false;
|
|
1984
|
+
}
|
|
1985
|
+
s.fields.iter().all(|f| {
|
|
1986
|
+
if f.nillable
|
|
1987
|
+
|| f.is_cycle_cut
|
|
1988
|
+
|| f.xml_name.contains(':')
|
|
1989
|
+
|| f.type_ref.is_list()
|
|
1990
|
+
|| f.type_ref.is_boxed()
|
|
1991
|
+
{
|
|
1992
|
+
return false;
|
|
1993
|
+
}
|
|
1994
|
+
match f.kind {
|
|
1995
|
+
FieldKind::Element if &f.namespace != namespace => return false,
|
|
1996
|
+
FieldKind::Attribute if f.namespace.is_some() => return false,
|
|
1997
|
+
FieldKind::Element | FieldKind::Attribute | FieldKind::Text => {}
|
|
1998
|
+
_ => return false,
|
|
1999
|
+
}
|
|
2000
|
+
match &f.type_ref {
|
|
2001
|
+
TypeRef::Named(q) => match ir.types.get(q) {
|
|
2002
|
+
Some(TypeDef::Struct(child)) => {
|
|
2003
|
+
supported(child, ir, namespace, &mut seen.clone())
|
|
2004
|
+
}
|
|
2005
|
+
Some(TypeDef::Enum(_)) => true,
|
|
2006
|
+
_ => false,
|
|
2007
|
+
},
|
|
2008
|
+
TypeRef::Primitive(_) => true,
|
|
2009
|
+
_ => false,
|
|
2010
|
+
}
|
|
2011
|
+
})
|
|
2012
|
+
}
|
|
2013
|
+
if s.fields.len() != 1
|
|
2014
|
+
|| s.fields[0].kind != FieldKind::Element
|
|
2015
|
+
|| !s.fields[0].cardinality.is_list()
|
|
2016
|
+
{
|
|
2017
|
+
return;
|
|
2018
|
+
}
|
|
2019
|
+
let field = &s.fields[0];
|
|
2020
|
+
let mut methods = HashSet::new();
|
|
2021
|
+
for root in ir.elements.values() {
|
|
2022
|
+
if root.type_ref != TypeRef::Named(s.qname.clone())
|
|
2023
|
+
|| root.nillable
|
|
2024
|
+
|| !supported(s, ir, &root.qname.namespace, &mut HashSet::new())
|
|
2025
|
+
{
|
|
2026
|
+
continue;
|
|
2027
|
+
}
|
|
2028
|
+
let name = type_ident(&s.qname);
|
|
2029
|
+
let item_type = self.format_rust_type_ref(&field.type_ref, lifetimes);
|
|
2030
|
+
let impl_type = if self.options.zero_copy && lifetimes.contains(&s.qname) {
|
|
2031
|
+
format!("impl<'a> {name}<'a>")
|
|
2032
|
+
} else {
|
|
2033
|
+
format!("impl {name}")
|
|
2034
|
+
};
|
|
2035
|
+
let base_method = format!("write_{}_items", AsSnakeCase(&root.qname.local));
|
|
2036
|
+
let mut method = base_method.clone();
|
|
2037
|
+
let mut suffix = 2;
|
|
2038
|
+
while !methods.insert(method.clone()) {
|
|
2039
|
+
method = format!("{base_method}_{suffix}");
|
|
2040
|
+
suffix += 1;
|
|
2041
|
+
}
|
|
2042
|
+
writeln!(out, "\n{impl_type} {{").unwrap();
|
|
2043
|
+
out.push_str(" /// Produce a document incrementally, retaining only the current item.\n /// Errors may leave partial XML in the sink; publish files only after success.\n");
|
|
2044
|
+
writeln!(out, " pub fn {method}<W: std::io::Write, I: IntoIterator<Item = {item_type}>>(sink: &mut W, items: I) -> Result<()> {{").unwrap();
|
|
2045
|
+
out.push_str(" let writer = &mut Writer::new(sink);\n");
|
|
2046
|
+
writeln!(
|
|
2047
|
+
out,
|
|
2048
|
+
" let {}start = BytesStart::new({:?});",
|
|
2049
|
+
if root.qname.namespace.is_some() {
|
|
2050
|
+
"mut "
|
|
2051
|
+
} else {
|
|
2052
|
+
""
|
|
2053
|
+
},
|
|
2054
|
+
root.qname.local
|
|
2055
|
+
)
|
|
2056
|
+
.unwrap();
|
|
2057
|
+
if let Some(ns) = &root.qname.namespace {
|
|
2058
|
+
writeln!(out, " start.push_attribute((\"xmlns\", {ns:?}));").unwrap();
|
|
2059
|
+
}
|
|
2060
|
+
out.push_str(" writer.write_event(Event::Start(start))?;\n let mut count = 0usize;\n");
|
|
2061
|
+
let mut checks = String::new();
|
|
2062
|
+
if let crate::ir::OccursLimit::Count(max) = field.cardinality.max_occurs {
|
|
2063
|
+
writeln!(checks, " if count == {max} {{ return Err(PolyXmlError::SchemaError(\"maxOccurs exceeded\".into())); }}").unwrap();
|
|
2064
|
+
}
|
|
2065
|
+
checks.push_str(" count = count.checked_add(1).ok_or_else(|| PolyXmlError::SchemaError(\"item count overflow\".into()))?;\n");
|
|
2066
|
+
self.emit_pattern_check(&mut checks, field, "&item.to_string()", ir);
|
|
2067
|
+
self.emit_element_serialize_from(out, field, "items", ir, Some("items"), &checks);
|
|
2068
|
+
if field.cardinality.min_occurs > 0 {
|
|
2069
|
+
writeln!(out, " if count < {} {{ return Err(PolyXmlError::SchemaError(\"minOccurs not satisfied\".into())); }}", field.cardinality.min_occurs).unwrap();
|
|
2070
|
+
}
|
|
2071
|
+
writeln!(out, " writer.write_event(Event::End(BytesEnd::new({:?})))?;\n Ok(())\n }}\n}}", root.qname.local).unwrap();
|
|
2072
|
+
}
|
|
1943
2073
|
}
|
|
1944
2074
|
|
|
1945
2075
|
fn emit_integer_bounds(
|
|
@@ -2406,6 +2536,18 @@ impl RustCodegen {
|
|
|
2406
2536
|
field: &FieldDef,
|
|
2407
2537
|
rust_name: &str,
|
|
2408
2538
|
ir: &SchemaIR,
|
|
2539
|
+
) {
|
|
2540
|
+
self.emit_element_serialize_from(out, field, rust_name, ir, None, "");
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
fn emit_element_serialize_from(
|
|
2544
|
+
&self,
|
|
2545
|
+
out: &mut String,
|
|
2546
|
+
field: &FieldDef,
|
|
2547
|
+
rust_name: &str,
|
|
2548
|
+
ir: &SchemaIR,
|
|
2549
|
+
source: Option<&str>,
|
|
2550
|
+
before_item: &str,
|
|
2409
2551
|
) {
|
|
2410
2552
|
let is_list = field.cardinality.is_list() || field.type_ref.is_list();
|
|
2411
2553
|
let is_optional = field.cardinality.is_optional() || field.nillable;
|
|
@@ -2415,7 +2557,11 @@ impl RustCodegen {
|
|
|
2415
2557
|
let is_enum = self.field_is_enum(&field.type_ref, ir).is_some();
|
|
2416
2558
|
|
|
2417
2559
|
if is_list {
|
|
2418
|
-
let
|
|
2560
|
+
let source = source
|
|
2561
|
+
.map(str::to_owned)
|
|
2562
|
+
.unwrap_or_else(|| format!("&self.{rust_name}"));
|
|
2563
|
+
let _ = writeln!(out, " for item in {source} {{");
|
|
2564
|
+
out.push_str(before_item);
|
|
2419
2565
|
if is_string {
|
|
2420
2566
|
let _ = writeln!(
|
|
2421
2567
|
out,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
use std::collections::HashMap;
|
|
2
|
+
use std::sync::atomic::{AtomicBool, Ordering};
|
|
2
3
|
use std::sync::{Arc, RwLock};
|
|
3
4
|
|
|
4
5
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
@@ -106,6 +107,12 @@ impl FieldSchema {
|
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
#[derive(Debug, Default)]
|
|
111
|
+
struct VariantRegistry {
|
|
112
|
+
schemas: RwLock<Vec<Arc<ModelSchema>>>,
|
|
113
|
+
populated: AtomicBool,
|
|
114
|
+
}
|
|
115
|
+
|
|
109
116
|
#[derive(Debug, Clone)]
|
|
110
117
|
pub struct ModelSchema {
|
|
111
118
|
pub name: String,
|
|
@@ -125,7 +132,7 @@ pub struct ModelSchema {
|
|
|
125
132
|
pub content_pattern: Option<regex::Regex>,
|
|
126
133
|
/// Concrete derivations eligible for `xsi:type` dispatch. Python may
|
|
127
134
|
/// refresh this registry when subclasses are defined after first use.
|
|
128
|
-
variants: Arc<
|
|
135
|
+
variants: Arc<VariantRegistry>,
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
impl ModelSchema {
|
|
@@ -136,12 +143,27 @@ impl ModelSchema {
|
|
|
136
143
|
/// Register the concrete derivations eligible for `xsi:type` dispatch.
|
|
137
144
|
/// Replaces the registry when subclasses are discovered after first use.
|
|
138
145
|
pub fn set_variants(&self, variants: Vec<Arc<ModelSchema>>) {
|
|
139
|
-
|
|
146
|
+
let mut registered = self
|
|
147
|
+
.variants
|
|
148
|
+
.schemas
|
|
149
|
+
.write()
|
|
150
|
+
.unwrap_or_else(|p| p.into_inner());
|
|
151
|
+
*registered = variants;
|
|
152
|
+
// Publish emptiness while holding the registry lock. Cloned schemas
|
|
153
|
+
// share this flag, so later registration/clearing cannot leave a stale
|
|
154
|
+
// per-schema dispatch plan. Nonempty lookups still use the lock.
|
|
155
|
+
self.variants
|
|
156
|
+
.populated
|
|
157
|
+
.store(!registered.is_empty(), Ordering::Release);
|
|
140
158
|
}
|
|
141
159
|
|
|
142
160
|
/// Registered derivations for `xsi:type` dispatch (empty when none).
|
|
143
161
|
pub fn variants(&self) -> Vec<Arc<ModelSchema>> {
|
|
162
|
+
if !self.has_variants() {
|
|
163
|
+
return Vec::new();
|
|
164
|
+
}
|
|
144
165
|
self.variants
|
|
166
|
+
.schemas
|
|
145
167
|
.read()
|
|
146
168
|
.unwrap_or_else(|p| p.into_inner())
|
|
147
169
|
.clone()
|
|
@@ -149,16 +171,16 @@ impl ModelSchema {
|
|
|
149
171
|
|
|
150
172
|
/// Whether any `xsi:type` derivations are registered for this type.
|
|
151
173
|
pub fn has_variants(&self) -> bool {
|
|
152
|
-
|
|
153
|
-
.variants
|
|
154
|
-
.read()
|
|
155
|
-
.unwrap_or_else(|p| p.into_inner())
|
|
156
|
-
.is_empty()
|
|
174
|
+
self.variants.populated.load(Ordering::Acquire)
|
|
157
175
|
}
|
|
158
176
|
|
|
159
177
|
/// Look up a derivation by the QName local part of an `xsi:type` value.
|
|
160
178
|
pub fn find_variant(&self, local: &[u8]) -> Option<Arc<ModelSchema>> {
|
|
179
|
+
if !self.has_variants() {
|
|
180
|
+
return None;
|
|
181
|
+
}
|
|
161
182
|
self.variants
|
|
183
|
+
.schemas
|
|
162
184
|
.read()
|
|
163
185
|
.unwrap_or_else(|p| p.into_inner())
|
|
164
186
|
.iter()
|
|
@@ -168,7 +190,11 @@ impl ModelSchema {
|
|
|
168
190
|
|
|
169
191
|
/// Look up a derivation by its complete QName.
|
|
170
192
|
pub fn find_variant_qname(&self, namespace: &str, local: &[u8]) -> Option<Arc<ModelSchema>> {
|
|
193
|
+
if !self.has_variants() {
|
|
194
|
+
return None;
|
|
195
|
+
}
|
|
171
196
|
self.variants
|
|
197
|
+
.schemas
|
|
172
198
|
.read()
|
|
173
199
|
.unwrap_or_else(|p| p.into_inner())
|
|
174
200
|
.iter()
|
|
@@ -180,7 +206,11 @@ impl ModelSchema {
|
|
|
180
206
|
|
|
181
207
|
/// Whether `candidate` is a registered derivation of `self`.
|
|
182
208
|
pub fn matches_variant(&self, candidate: &ModelSchema) -> bool {
|
|
209
|
+
if !self.has_variants() {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
183
212
|
self.variants
|
|
213
|
+
.schemas
|
|
184
214
|
.read()
|
|
185
215
|
.unwrap_or_else(|p| p.into_inner())
|
|
186
216
|
.iter()
|
|
@@ -664,7 +694,7 @@ impl ModelSchemaBuilder {
|
|
|
664
694
|
is_abstract: self.is_abstract,
|
|
665
695
|
strict_root: self.strict_root,
|
|
666
696
|
content_pattern: self.content_pattern,
|
|
667
|
-
variants: Arc::new(
|
|
697
|
+
variants: Arc::new(VariantRegistry::default()),
|
|
668
698
|
})
|
|
669
699
|
}
|
|
670
700
|
}
|
|
@@ -15,6 +15,8 @@ pub struct Document {
|
|
|
15
15
|
groups: BTreeMap<QName, Model>,
|
|
16
16
|
named: BTreeMap<QName, Model>,
|
|
17
17
|
anonymous: Vec<(String, Model)>,
|
|
18
|
+
#[serde(default)]
|
|
19
|
+
unsupported_attribute_types: BTreeSet<QName>,
|
|
18
20
|
}
|
|
19
21
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
20
22
|
enum Model {
|
|
@@ -115,14 +117,7 @@ fn node(
|
|
|
115
117
|
Event::Start(child)
|
|
116
118
|
if matches!(
|
|
117
119
|
strip_prefix(child.name().into_inner()),
|
|
118
|
-
"annotation"
|
|
119
|
-
| "simpleType"
|
|
120
|
-
| "attribute"
|
|
121
|
-
| "attributeGroup"
|
|
122
|
-
| "anyAttribute"
|
|
123
|
-
| "unique"
|
|
124
|
-
| "key"
|
|
125
|
-
| "keyref"
|
|
120
|
+
"annotation" | "simpleType" | "unique" | "key" | "keyref"
|
|
126
121
|
) =>
|
|
127
122
|
{
|
|
128
123
|
reader.read_to_end(child.name())?;
|
|
@@ -130,14 +125,7 @@ fn node(
|
|
|
130
125
|
Event::Empty(child)
|
|
131
126
|
if matches!(
|
|
132
127
|
strip_prefix(child.name().into_inner()),
|
|
133
|
-
"annotation"
|
|
134
|
-
| "simpleType"
|
|
135
|
-
| "attribute"
|
|
136
|
-
| "attributeGroup"
|
|
137
|
-
| "anyAttribute"
|
|
138
|
-
| "unique"
|
|
139
|
-
| "key"
|
|
140
|
-
| "keyref"
|
|
128
|
+
"annotation" | "simpleType" | "unique" | "key" | "keyref"
|
|
141
129
|
) => {}
|
|
142
130
|
Event::Start(child) => {
|
|
143
131
|
result
|
|
@@ -256,6 +244,28 @@ fn particle(node: &Node, ns: Option<&str>, qualified: bool) -> Option<Model> {
|
|
|
256
244
|
Some(repeat(node, model))
|
|
257
245
|
}
|
|
258
246
|
impl Document {
|
|
247
|
+
/// Whether a named type has plain sequence content in one element namespace.
|
|
248
|
+
/// Source QNames retain local `form` and `elementFormDefault` distinctions.
|
|
249
|
+
pub(crate) fn uniform_sequence(
|
|
250
|
+
&self,
|
|
251
|
+
name: &QName,
|
|
252
|
+
namespace: &Option<String>,
|
|
253
|
+
) -> Option<bool> {
|
|
254
|
+
fn uniform(model: &Model, namespace: &Option<String>) -> bool {
|
|
255
|
+
match model {
|
|
256
|
+
Model::Element(q, _) => &q.namespace == namespace,
|
|
257
|
+
Model::Sequence(parts) => parts.iter().all(|p| uniform(p, namespace)),
|
|
258
|
+
Model::Repeat(part, _, _) if matches!(part.as_ref(), Model::Element(..)) => {
|
|
259
|
+
uniform(part, namespace)
|
|
260
|
+
}
|
|
261
|
+
_ => false,
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
self.named.get(name).map(|model| {
|
|
265
|
+
!self.unsupported_attribute_types.contains(name) && uniform(model, namespace)
|
|
266
|
+
})
|
|
267
|
+
}
|
|
268
|
+
|
|
259
269
|
pub fn parse(xml: &str) -> Result<Self, SchemaError> {
|
|
260
270
|
let mut reader = Reader::from_str(xml);
|
|
261
271
|
let root = loop {
|
|
@@ -273,13 +283,38 @@ impl Document {
|
|
|
273
283
|
groups: BTreeMap::new(),
|
|
274
284
|
named: BTreeMap::new(),
|
|
275
285
|
anonymous: Vec::new(),
|
|
286
|
+
unsupported_attribute_types: BTreeSet::new(),
|
|
276
287
|
};
|
|
277
|
-
fn
|
|
288
|
+
fn qualified_attributes(node: &Node, default_qualified: bool) -> bool {
|
|
289
|
+
matches!(node.tag.as_str(), "attributeGroup" | "anyAttribute")
|
|
290
|
+
|| (node.tag == "attribute"
|
|
291
|
+
&& (node.attr("ref").is_some()
|
|
292
|
+
|| match node.attr("form") {
|
|
293
|
+
Some("qualified") => true,
|
|
294
|
+
Some("unqualified") => false,
|
|
295
|
+
_ => default_qualified,
|
|
296
|
+
}))
|
|
297
|
+
|| node
|
|
298
|
+
.children
|
|
299
|
+
.iter()
|
|
300
|
+
.any(|child| qualified_attributes(child, default_qualified))
|
|
301
|
+
}
|
|
302
|
+
fn collect(
|
|
303
|
+
node: &Node,
|
|
304
|
+
document: &mut Document,
|
|
305
|
+
qualified: bool,
|
|
306
|
+
attributes_qualified: bool,
|
|
307
|
+
) {
|
|
278
308
|
let ns = document.namespace.as_deref();
|
|
279
309
|
if node.tag == "complexType" {
|
|
280
310
|
let model = content(node, ns, qualified);
|
|
281
311
|
if let Some(name) = node.attr("name") {
|
|
282
312
|
document.named.insert(QName::new(ns, name), model);
|
|
313
|
+
if qualified_attributes(node, attributes_qualified) {
|
|
314
|
+
document
|
|
315
|
+
.unsupported_attribute_types
|
|
316
|
+
.insert(QName::new(ns, name));
|
|
317
|
+
}
|
|
283
318
|
} else {
|
|
284
319
|
document.anonymous.push((
|
|
285
320
|
format!("anonymous complexType at byte {}", node.position),
|
|
@@ -288,7 +323,7 @@ impl Document {
|
|
|
288
323
|
}
|
|
289
324
|
}
|
|
290
325
|
for child in &node.children {
|
|
291
|
-
collect(child, document, qualified);
|
|
326
|
+
collect(child, document, qualified, attributes_qualified);
|
|
292
327
|
}
|
|
293
328
|
}
|
|
294
329
|
for child in &root.children {
|
|
@@ -301,7 +336,12 @@ impl Document {
|
|
|
301
336
|
}
|
|
302
337
|
}
|
|
303
338
|
}
|
|
304
|
-
collect(
|
|
339
|
+
collect(
|
|
340
|
+
&root,
|
|
341
|
+
&mut document,
|
|
342
|
+
qualified,
|
|
343
|
+
root.attr("attributeFormDefault") == Some("qualified"),
|
|
344
|
+
);
|
|
305
345
|
Ok(document)
|
|
306
346
|
}
|
|
307
347
|
pub fn adopt_namespace(&mut self, namespace: &str) {
|
|
@@ -344,6 +384,13 @@ impl Document {
|
|
|
344
384
|
_ => {}
|
|
345
385
|
}
|
|
346
386
|
}
|
|
387
|
+
self.unsupported_attribute_types = std::mem::take(&mut self.unsupported_attribute_types)
|
|
388
|
+
.into_iter()
|
|
389
|
+
.map(|mut q| {
|
|
390
|
+
name(&mut q, namespace);
|
|
391
|
+
q
|
|
392
|
+
})
|
|
393
|
+
.collect();
|
|
347
394
|
for collection in [&mut self.groups, &mut self.named] {
|
|
348
395
|
*collection = std::mem::take(collection)
|
|
349
396
|
.into_iter()
|
|
@@ -1505,3 +1505,52 @@ assert_eq!(parsed,value);let object:serde_json::Value=serde_json::from_str(&json
|
|
|
1505
1505
|
);
|
|
1506
1506
|
}
|
|
1507
1507
|
}
|
|
1508
|
+
|
|
1509
|
+
#[test]
|
|
1510
|
+
fn incremental_root_writer_is_schema_scoped() {
|
|
1511
|
+
let xsd = include_str!("../../../tests/fixtures/incremental/items.xsd");
|
|
1512
|
+
for zero_copy in [true, false] {
|
|
1513
|
+
let ir = XsdParser::new().parse_str(xsd).unwrap();
|
|
1514
|
+
let code = RustCodegen::new(RustOptions {
|
|
1515
|
+
zero_copy,
|
|
1516
|
+
..Default::default()
|
|
1517
|
+
})
|
|
1518
|
+
.generate_module(&ir);
|
|
1519
|
+
assert!(code.contains("pub fn write_batch_items"));
|
|
1520
|
+
assert!(code.contains("for item in items"));
|
|
1521
|
+
assert!(code.contains("start.push_attribute((\"xmlns\", \"urn:items\"))"));
|
|
1522
|
+
assert!(code.contains("if count < 1"));
|
|
1523
|
+
assert!(code.contains("item.encode_xml(writer, Some(\"Item\"))"));
|
|
1524
|
+
let bounded = xsd.replace("maxOccurs=\"unbounded\"", "maxOccurs=\"2\"");
|
|
1525
|
+
let ir = XsdParser::new().parse_str(&bounded).unwrap();
|
|
1526
|
+
let code = RustCodegen::new(RustOptions::default()).generate_module(&ir);
|
|
1527
|
+
assert!(code.contains("if count == 2"));
|
|
1528
|
+
for unsupported in [
|
|
1529
|
+
xsd.replace(
|
|
1530
|
+
"elementFormDefault=\"qualified\"",
|
|
1531
|
+
"elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\"",
|
|
1532
|
+
),
|
|
1533
|
+
xsd.replace("<xs:sequence>", "<xs:sequence minOccurs=\"0\">"),
|
|
1534
|
+
xsd.replace(
|
|
1535
|
+
"name=\"Item\" type=\"t:ItemType\"",
|
|
1536
|
+
"name=\"Item\" type=\"t:ItemType\" nillable=\"true\"",
|
|
1537
|
+
),
|
|
1538
|
+
xsd.replace(
|
|
1539
|
+
"elementFormDefault=\"qualified\"",
|
|
1540
|
+
"elementFormDefault=\"unqualified\"",
|
|
1541
|
+
),
|
|
1542
|
+
xsd.replace(
|
|
1543
|
+
"name=\"Batch\" type=\"t:BatchType\"",
|
|
1544
|
+
"name=\"Batch\" type=\"t:BatchType\" nillable=\"true\"",
|
|
1545
|
+
),
|
|
1546
|
+
] {
|
|
1547
|
+
let ir = XsdParser::new().parse_str(&unsupported).unwrap();
|
|
1548
|
+
let code = RustCodegen::new(RustOptions::default()).generate_module(&ir);
|
|
1549
|
+
assert!(
|
|
1550
|
+
!code.contains("pub fn write_batch_items"),
|
|
1551
|
+
"{unsupported}\n{:?}",
|
|
1552
|
+
ir.upa_documents
|
|
1553
|
+
);
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
use std::sync::Arc;
|
|
2
|
+
|
|
3
|
+
use polyxml::schema::ModelSchema;
|
|
4
|
+
|
|
5
|
+
#[test]
|
|
6
|
+
fn registration_and_clearing_are_visible_to_schema_clones() {
|
|
7
|
+
let base = ModelSchema::builder("Base").build();
|
|
8
|
+
let clone = (*base).clone();
|
|
9
|
+
let derived = ModelSchema::builder("Derived")
|
|
10
|
+
.namespace("urn:derived")
|
|
11
|
+
.build();
|
|
12
|
+
assert!(!clone.has_variants());
|
|
13
|
+
assert!(clone.variants().is_empty());
|
|
14
|
+
base.set_variants(vec![Arc::clone(&derived)]);
|
|
15
|
+
assert!(clone.has_variants());
|
|
16
|
+
assert!(Arc::ptr_eq(&clone.variants()[0], &derived));
|
|
17
|
+
assert!(Arc::ptr_eq(
|
|
18
|
+
&clone.find_variant(b"Derived").unwrap(),
|
|
19
|
+
&derived
|
|
20
|
+
));
|
|
21
|
+
assert!(clone.find_variant_qname("urn:other", b"Derived").is_none());
|
|
22
|
+
assert!(Arc::ptr_eq(
|
|
23
|
+
&clone.find_variant_qname("urn:derived", b"Derived").unwrap(),
|
|
24
|
+
&derived
|
|
25
|
+
));
|
|
26
|
+
assert!(clone.matches_variant(&derived));
|
|
27
|
+
clone.set_variants(Vec::new());
|
|
28
|
+
assert!(!base.has_variants());
|
|
29
|
+
assert!(base.variants().is_empty());
|
|
30
|
+
assert!(base.find_variant(b"Derived").is_none());
|
|
31
|
+
assert!(!base.matches_variant(&derived));
|
|
32
|
+
clone.set_variants(vec![Arc::clone(&derived)]);
|
|
33
|
+
assert!(base.has_variants());
|
|
34
|
+
assert!(base.matches_variant(&derived));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#[test]
|
|
38
|
+
fn concurrent_registry_updates_keep_complete_variant_snapshots() {
|
|
39
|
+
let base = ModelSchema::builder("Base").build();
|
|
40
|
+
let derived = ModelSchema::builder("Derived").build();
|
|
41
|
+
std::thread::scope(|scope| {
|
|
42
|
+
scope.spawn(|| {
|
|
43
|
+
for index in 0..4096 {
|
|
44
|
+
base.set_variants(if index % 2 == 0 {
|
|
45
|
+
Vec::new()
|
|
46
|
+
} else {
|
|
47
|
+
vec![Arc::clone(&derived)]
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
base.set_variants(vec![Arc::clone(&derived)]);
|
|
51
|
+
});
|
|
52
|
+
for _ in 0..4 {
|
|
53
|
+
scope.spawn(|| {
|
|
54
|
+
for _ in 0..4096 {
|
|
55
|
+
// These calls can observe different registry revisions.
|
|
56
|
+
// Each populated snapshot must contain the original Arc.
|
|
57
|
+
let _ = base.has_variants();
|
|
58
|
+
let variants = base.variants();
|
|
59
|
+
assert!(variants.len() <= 1);
|
|
60
|
+
for variant in variants {
|
|
61
|
+
assert!(Arc::ptr_eq(&variant, &derived));
|
|
62
|
+
}
|
|
63
|
+
if let Some(variant) = base.find_variant(b"Derived") {
|
|
64
|
+
assert!(Arc::ptr_eq(&variant, &derived));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
assert!(base.has_variants());
|
|
71
|
+
assert!(Arc::ptr_eq(&base.variants()[0], &derived));
|
|
72
|
+
base.set_variants(Vec::new());
|
|
73
|
+
assert!(!base.has_variants());
|
|
74
|
+
assert!(base.variants().is_empty());
|
|
75
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/benches/support/tag_dispatch_fixtures.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_inherited_simple_content.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyxml-0.34.8 → polyxml-0.35.0}/crates/polyxml-core/tests/test_schema_attribute_entities.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|