Skip to content

Commit 5fb7be8

Browse files
committedMar 21, 2025·
Fix issue with maxLength restrictions
We mistakenly have interpreted the `maxLength` restriction facet as value for the maximum occurrences of an element.
1 parent 0aea263 commit 5fb7be8

File tree

10 files changed

+143
-51
lines changed

10 files changed

+143
-51
lines changed
 

‎src/interpreter/type_builder.rs

-25
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,6 @@ macro_rules! init_any {
7575
}};
7676
}
7777

78-
/// Get the type `$variant` of a `$builder` or panic if the variant does not match.
79-
macro_rules! get_any {
80-
($builder:expr, $variant:ident) => {
81-
match &mut $builder.type_ {
82-
None => crate::unreachable!("Type is not assigned yet!"),
83-
Some(Type::$variant(ret)) => ret,
84-
Some(e) => crate::unreachable!("Type is expected to be a {:?}", e),
85-
}
86-
};
87-
}
88-
8978
/// Get the type `$variant` of a `$builder` or set the type variant if unset.
9079
macro_rules! get_or_init_any {
9180
($builder:expr, $variant:ident) => {
@@ -735,20 +724,6 @@ impl<'a, 'schema, 'state> TypeBuilder<'a, 'schema, 'state> {
735724
fn apply_facet(&mut self, ty: &Facet) -> Result<(), Error> {
736725
match ty {
737726
Facet::Enumeration(x) => self.apply_enumeration(x)?,
738-
Facet::MinLength(x) => {
739-
let ti = get_any!(self, Reference);
740-
ti.min_occurs = x
741-
.value
742-
.parse::<usize>()
743-
.map_err(|_| Error::InvalidValue("value"))?;
744-
}
745-
Facet::MaxLength(x) => {
746-
let ti = get_any!(self, Reference);
747-
ti.max_occurs = x
748-
.value
749-
.parse::<MaxOccurs>()
750-
.map_err(|_| Error::InvalidValue("value"))?;
751-
}
752727
x => tracing::warn!("Unknown facet: {x:#?}"),
753728
}
754729

‎tests/feature/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ mod sequence;
2121
mod sequence_with_choice;
2222
mod simple_content;
2323
mod simple_type;
24+
mod simple_type_max_length;
2425
mod static_list;
2526
mod tuple_with_integer;
2627
mod tuple_with_string;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<tns:Name xmlns:tns="http://example.com">string</tns:Name>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub type Name = String;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub const NS_XS: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema");
2+
pub const NS_XML: Namespace = Namespace::new_const(b"http://www.w3.org/XML/1998/namespace");
3+
pub const NS_TNS: Namespace = Namespace::new_const(b"http://example.com");
4+
use xsd_parser::schema::Namespace;
5+
pub type Name = String;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub type Name = String;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub type Name = String;
+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use xsd_parser::{generator::SerdeSupport, types::IdentType, Config};
2+
3+
use crate::utils::{generate_test, ConfigEx};
4+
5+
#[test]
6+
fn generate_default() {
7+
generate_test(
8+
"tests/feature/simple_type_max_length/schema.xsd",
9+
"tests/feature/simple_type_max_length/expected/default.rs",
10+
Config::test_default().with_generate([(IdentType::Element, "tns:Name")]),
11+
);
12+
}
13+
14+
#[test]
15+
fn generate_quick_xml() {
16+
generate_test(
17+
"tests/feature/simple_type_max_length/schema.xsd",
18+
"tests/feature/simple_type_max_length/expected/quick_xml.rs",
19+
Config::test_default()
20+
.with_quick_xml()
21+
.with_generate([(IdentType::Element, "tns:Name")]),
22+
);
23+
}
24+
25+
#[test]
26+
fn generate_serde_xml_rs() {
27+
generate_test(
28+
"tests/feature/simple_type_max_length/schema.xsd",
29+
"tests/feature/simple_type_max_length/expected/serde_xml_rs.rs",
30+
Config::test_default()
31+
.with_serde_support(SerdeSupport::SerdeXmlRs)
32+
.with_generate([(IdentType::Element, "tns:Name")]),
33+
);
34+
}
35+
36+
#[test]
37+
fn generate_serde_quick_xml() {
38+
generate_test(
39+
"tests/feature/simple_type_max_length/schema.xsd",
40+
"tests/feature/simple_type_max_length/expected/serde_quick_xml.rs",
41+
Config::test_default()
42+
.with_serde_support(SerdeSupport::QuickXml)
43+
.with_generate([(IdentType::Element, "tns:Name")]),
44+
);
45+
}
46+
47+
#[test]
48+
#[cfg(not(feature = "update-expectations"))]
49+
fn read_quick_xml() {
50+
use quick_xml::Name;
51+
52+
let obj = crate::utils::quick_xml_read_test::<Name, _>(
53+
"tests/feature/simple_type_max_length/example/default.xml",
54+
);
55+
56+
assert_eq!(obj, "string");
57+
}
58+
59+
#[test]
60+
#[cfg(not(feature = "update-expectations"))]
61+
fn read_serde_xml_rs() {
62+
use serde_xml_rs::Name;
63+
64+
let obj = crate::utils::serde_xml_rs_read_test::<Name, _>(
65+
"tests/feature/simple_type_max_length/example/default.xml",
66+
);
67+
68+
assert_eq!(obj, "string");
69+
}
70+
71+
#[test]
72+
#[cfg(not(feature = "update-expectations"))]
73+
fn read_serde_quick_xml() {
74+
use serde_quick_xml::Name;
75+
76+
let obj = crate::utils::serde_quick_xml_read_test::<Name, _>(
77+
"tests/feature/simple_type_max_length/example/default.xml",
78+
);
79+
80+
assert_eq!(obj, "string");
81+
}
82+
83+
#[cfg(not(feature = "update-expectations"))]
84+
mod default {
85+
#![allow(unused_imports)]
86+
87+
include!("expected/default.rs");
88+
}
89+
90+
#[cfg(not(feature = "update-expectations"))]
91+
mod quick_xml {
92+
#![allow(unused_imports)]
93+
94+
include!("expected/quick_xml.rs");
95+
}
96+
97+
#[cfg(not(feature = "update-expectations"))]
98+
mod serde_xml_rs {
99+
#![allow(unused_imports)]
100+
101+
include!("expected/serde_xml_rs.rs");
102+
}
103+
104+
#[cfg(not(feature = "update-expectations"))]
105+
mod serde_quick_xml {
106+
#![allow(unused_imports)]
107+
108+
include!("expected/serde_quick_xml.rs");
109+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
3+
xmlns:tns="http://example.com"
4+
targetNamespace="http://example.com"
5+
elementFormDefault="qualified">
6+
<xs:simpleType name="NameType">
7+
<xs:restriction base="xs:string">
8+
<xs:maxLength value="30"/>
9+
</xs:restriction>
10+
</xs:simpleType>
11+
12+
<xs:element name="Name" type="tns:NameType"/>
13+
</xs:schema>

‎tests/schema/xml_schema/expected/quick_xml.rs

+11-26
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ impl DeserializeBytes for DefaultOpenContentModeType {
545545
pub struct WildcardType {
546546
pub id: Option<String>,
547547
pub namespace: Option<NamespaceListType>,
548-
pub not_namespace: Option<NotNamespaceType>,
548+
pub not_namespace: Option<BasicNamespaceListType>,
549549
pub process_contents: ProcessContentsType,
550550
pub annotation: Option<AnnotationElementType>,
551551
}
@@ -687,7 +687,7 @@ impl WithDeserializer for OpenContentElementType {
687687
pub struct AnyAttributeElementType {
688688
pub id: Option<String>,
689689
pub namespace: Option<NamespaceListType>,
690-
pub not_namespace: Option<NotNamespaceType>,
690+
pub not_namespace: Option<BasicNamespaceListType>,
691691
pub process_contents: ProcessContentsType,
692692
pub not_q_name: Option<QnameListAType>,
693693
pub annotation: Option<AnnotationElementType>,
@@ -731,7 +731,7 @@ impl DeserializeBytes for AllNNIType {
731731
pub struct AnyElementType {
732732
pub id: Option<String>,
733733
pub namespace: Option<NamespaceListType>,
734-
pub not_namespace: Option<NotNamespaceType>,
734+
pub not_namespace: Option<BasicNamespaceListType>,
735735
pub process_contents: ProcessContentsType,
736736
pub not_q_name: Option<QnameListType>,
737737
pub min_occurs: usize,
@@ -869,8 +869,8 @@ impl DeserializeBytes for NamespaceListType {
869869
}
870870
}
871871
#[derive(Debug, Clone, Default)]
872-
pub struct NotNamespaceType(pub Vec<BasicNamespaceListItemType>);
873-
impl DeserializeBytes for NotNamespaceType {
872+
pub struct BasicNamespaceListType(pub Vec<BasicNamespaceListItemType>);
873+
impl DeserializeBytes for BasicNamespaceListType {
874874
fn deserialize_bytes<R>(reader: &R, bytes: &[u8]) -> Result<Self, Error>
875875
where
876876
R: DeserializeReader,
@@ -1063,21 +1063,6 @@ pub struct FieldElementType {
10631063
impl WithDeserializer for FieldElementType {
10641064
type Deserializer = quick_xml_deserialize::FieldElementTypeDeserializer;
10651065
}
1066-
#[derive(Debug, Clone, Default)]
1067-
pub struct BasicNamespaceListType(pub Vec<BasicNamespaceListItemType>);
1068-
impl DeserializeBytes for BasicNamespaceListType {
1069-
fn deserialize_bytes<R>(reader: &R, bytes: &[u8]) -> Result<Self, Error>
1070-
where
1071-
R: DeserializeReader,
1072-
{
1073-
Ok(Self(
1074-
bytes
1075-
.split(|b| *b == b' ' || *b == b'|' || *b == b',' || *b == b';')
1076-
.map(|bytes| BasicNamespaceListItemType::deserialize_bytes(reader, bytes))
1077-
.collect::<Result<Vec<_>, _>>()?,
1078-
))
1079-
}
1080-
}
10811066
#[derive(Debug, Clone)]
10821067
pub enum BasicNamespaceListItemType {
10831068
String(String),
@@ -13218,7 +13203,7 @@ pub mod quick_xml_deserialize {
1321813203
pub struct WildcardTypeDeserializer {
1321913204
id: Option<String>,
1322013205
namespace: Option<super::NamespaceListType>,
13221-
not_namespace: Option<super::NotNamespaceType>,
13206+
not_namespace: Option<super::BasicNamespaceListType>,
1322213207
process_contents: super::ProcessContentsType,
1322313208
annotation: Option<super::AnnotationElementType>,
1322413209
state: Box<WildcardTypeDeserializerState>,
@@ -13237,7 +13222,7 @@ pub mod quick_xml_deserialize {
1323713222
{
1323813223
let mut id: Option<String> = None;
1323913224
let mut namespace: Option<super::NamespaceListType> = None;
13240-
let mut not_namespace: Option<super::NotNamespaceType> = None;
13225+
let mut not_namespace: Option<super::BasicNamespaceListType> = None;
1324113226
let mut process_contents: Option<super::ProcessContentsType> = None;
1324213227
for attrib in filter_xmlns_attributes(&bytes_start) {
1324313228
let attrib = attrib?;
@@ -16347,7 +16332,7 @@ pub mod quick_xml_deserialize {
1634716332
pub struct AnyAttributeElementTypeDeserializer {
1634816333
id: Option<String>,
1634916334
namespace: Option<super::NamespaceListType>,
16350-
not_namespace: Option<super::NotNamespaceType>,
16335+
not_namespace: Option<super::BasicNamespaceListType>,
1635116336
process_contents: super::ProcessContentsType,
1635216337
not_q_name: Option<super::QnameListAType>,
1635316338
annotation: Option<super::AnnotationElementType>,
@@ -16367,7 +16352,7 @@ pub mod quick_xml_deserialize {
1636716352
{
1636816353
let mut id: Option<String> = None;
1636916354
let mut namespace: Option<super::NamespaceListType> = None;
16370-
let mut not_namespace: Option<super::NotNamespaceType> = None;
16355+
let mut not_namespace: Option<super::BasicNamespaceListType> = None;
1637116356
let mut process_contents: Option<super::ProcessContentsType> = None;
1637216357
let mut not_q_name: Option<super::QnameListAType> = None;
1637316358
for attrib in filter_xmlns_attributes(&bytes_start) {
@@ -16829,7 +16814,7 @@ pub mod quick_xml_deserialize {
1682916814
pub struct AnyElementTypeDeserializer {
1683016815
id: Option<String>,
1683116816
namespace: Option<super::NamespaceListType>,
16832-
not_namespace: Option<super::NotNamespaceType>,
16817+
not_namespace: Option<super::BasicNamespaceListType>,
1683316818
process_contents: super::ProcessContentsType,
1683416819
not_q_name: Option<super::QnameListType>,
1683516820
min_occurs: usize,
@@ -16851,7 +16836,7 @@ pub mod quick_xml_deserialize {
1685116836
{
1685216837
let mut id: Option<String> = None;
1685316838
let mut namespace: Option<super::NamespaceListType> = None;
16854-
let mut not_namespace: Option<super::NotNamespaceType> = None;
16839+
let mut not_namespace: Option<super::BasicNamespaceListType> = None;
1685516840
let mut process_contents: Option<super::ProcessContentsType> = None;
1685616841
let mut not_q_name: Option<super::QnameListType> = None;
1685716842
let mut min_occurs: Option<usize> = None;

0 commit comments

Comments
 (0)
Please sign in to comment.