From cbcf2236bb9efcdcfbbbab9df9d75d81e2836d3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Oliveira?= Date: Fri, 10 Apr 2026 21:59:33 +0100 Subject: [PATCH 1/7] Fix bug checking the length of binary types When we have a restriction on a binary type to check for its length, the size that needs to be considered is the octet size. So for a `xs:hexBinary` that might be represented by a string of 4 caracteres it actually only has length 2. The same for `xs:base64Binary` but the computation of the length is not as straight forward. Here is the relevant part of the standard: **lenght** https://www.w3.org/TR/xmlschema11-2/#rf-length **hexBinary** https://www.w3.org/TR/xmlschema11-2/#hexBinary **base64Binary** https://www.w3.org/TR/xmlschema11-2/#base64Binary --- xsd-parser/src/models/meta/mod.rs | 14 + xsd-parser/src/models/meta/type_.rs | 8 +- .../state/generate_types/variant_processor.rs | 42 ++- xsd-parser/src/pipeline/renderer/steps/mod.rs | 28 ++ .../tests/feature/facets/example/default.xml | 4 +- .../tests/feature/facets/expected/default.rs | 90 +++++ .../feature/facets/expected/quick_xml.rs | 326 ++++++++++++++++++ .../facets/expected/serde_quick_xml.rs | 92 +++++ .../feature/facets/expected/serde_xml_rs.rs | 92 +++++ xsd-parser/tests/feature/facets/mod.rs | 10 + xsd-parser/tests/feature/facets/schema.xsd | 26 +- 11 files changed, 719 insertions(+), 13 deletions(-) diff --git a/xsd-parser/src/models/meta/mod.rs b/xsd-parser/src/models/meta/mod.rs index 3c6cb43f..cec5f7aa 100644 --- a/xsd-parser/src/models/meta/mod.rs +++ b/xsd-parser/src/models/meta/mod.rs @@ -35,6 +35,16 @@ pub use self::type_eq::TypeEq; pub use self::types::{MetaTypes, ModuleMeta, SchemaMeta}; pub use self::union::{UnionMeta, UnionMetaType, UnionMetaTypes}; +/// Indicate what type of binary value is expected +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +pub enum BinaryType { + /// Value is based on `xs:hexBinary`. + Hex, + + /// Value is based on `xs:base64Binary`. + Base64, +} + /// Constrains defined by the different facets of a type. #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct Constrains { @@ -58,6 +68,9 @@ pub struct Constrains { /// Defines the whitespace handling. pub whitespace: WhiteSpace, + + /// Indicates if the value is a binary primitive and which lexical rules it uses. + pub binary_type: Option, } impl Default for Constrains { @@ -73,6 +86,7 @@ impl Default for Constrains { min_length: None, max_length: None, whitespace: WhiteSpace::default(), + binary_type: None, } } } diff --git a/xsd-parser/src/models/meta/type_.rs b/xsd-parser/src/models/meta/type_.rs index 346ecbcc..677b28fb 100644 --- a/xsd-parser/src/models/meta/type_.rs +++ b/xsd-parser/src/models/meta/type_.rs @@ -11,8 +11,8 @@ use crate::models::schema::{xs::FormChoiceType, SchemaId}; use crate::models::TypeIdent; use super::{ - ComplexMeta, CustomMeta, DynamicMeta, EnumerationMeta, GroupMeta, MetaTypes, ReferenceMeta, - SimpleMeta, TypeEq, UnionMeta, + BinaryType, ComplexMeta, CustomMeta, DynamicMeta, EnumerationMeta, GroupMeta, MetaTypes, + ReferenceMeta, SimpleMeta, TypeEq, UnionMeta, }; /// Represents a fully interpreted type from an XML schema. @@ -39,6 +39,9 @@ pub struct MetaType { /// Documentation of the type extracted from `xs:documentation` nodes. pub documentation: Vec, + + /// Indicates if and what type of Binary is this type. + pub binary_type: Option, } /// Actual data variant a [`MetaType`] represents. @@ -131,6 +134,7 @@ impl MetaType { pub fn new(variant: MetaTypeVariant) -> Self { Self { variant, + binary_type: None, form: None, schema: None, display_name: None, diff --git a/xsd-parser/src/pipeline/interpreter/state/generate_types/variant_processor.rs b/xsd-parser/src/pipeline/interpreter/state/generate_types/variant_processor.rs index c19841c5..42178c7a 100644 --- a/xsd-parser/src/pipeline/interpreter/state/generate_types/variant_processor.rs +++ b/xsd-parser/src/pipeline/interpreter/state/generate_types/variant_processor.rs @@ -6,8 +6,8 @@ use std::str::from_utf8; use tracing::instrument; use crate::models::meta::{ - AnyAttributeMeta, AnyMeta, AttributeMeta, Base, DerivedTypeMeta, DynamicMeta, ElementMeta, - ElementMetaVariant, ElementMode, ElementsMeta, EnumerationMetaVariant, MetaType, + AnyAttributeMeta, AnyMeta, AttributeMeta, Base, BinaryType, DerivedTypeMeta, DynamicMeta, + ElementMeta, ElementMetaVariant, ElementMode, ElementsMeta, EnumerationMetaVariant, MetaType, MetaTypeVariant, ReferenceMeta, SimpleMeta, UnionMetaType, WhiteSpace, }; use crate::models::schema::xs::{ @@ -44,6 +44,9 @@ pub(super) struct VariantProcessor<'a, 'state, 'schema> { /// and `xs:documentation` nodes. documentation: Vec, + /// If the type is either based on `xs:hexBinary` or `xs:base64Binary`, indicate which of the two + binary_type: Option, + /// `true` if the simple content type of a complex type was already duplicated /// and is now unique for this type. is_simple_content_unique: bool, @@ -159,18 +162,26 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { type_mode: TypeMode::Unknown, content_mode: ContentMode::Unknown, documentation: Vec::new(), + binary_type: None, is_simple_content_unique: false, } } pub(super) fn finish(self) -> Result { - let Self { variant, owner, .. } = self; + let Self { + variant, + owner, + documentation, + binary_type, + .. + } = self; let variant = variant.ok_or(Error::NoType)?; let mut type_ = MetaType::new(variant); + type_.binary_type = binary_type; type_.form = Some(owner.current_schema().element_form_default); type_.schema = Some(owner.current_schema_id()); - type_.documentation = self.documentation; + type_.documentation = documentation; Ok(type_) } @@ -179,6 +190,7 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { let variant = self.variant.take().ok_or(Error::NoType)?; let mut type_ = MetaType::new(variant); + type_.binary_type = self.binary_type.clone(); type_.form = Some(self.owner.current_schema().element_form_default); type_.schema = Some(self.owner.current_schema_id()); swap(&mut type_.documentation, &mut self.documentation); @@ -193,6 +205,7 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { self.fixed = false; self.type_mode = TypeMode::Unknown; self.content_mode = ContentMode::Unknown; + self.binary_type = None; self.is_simple_content_unique = false; self.documentation.clear(); @@ -416,6 +429,7 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { .map(|base| { let base = self.owner.resolve_type_ident(base, IdentType::Type)?; + self.binary_type = self.resolve_binary_type(&base); self.copy_base_type(base, UpdateMode::Restriction) }) .transpose()?; @@ -589,6 +603,10 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { fn apply_restriction(&mut self, ty: &'schema RestrictionType) -> Result<(), Error> { use crate::models::schema::xs::RestrictionTypeContent as C; + let base = self.owner.resolve_type_ident(&ty.base, IdentType::Type)?; + let binary_type = self.resolve_binary_type(&base); + self.binary_type = binary_type; + for c in &ty.content { match c { C::OpenContent(_) | C::Assert(_) => (), @@ -1097,10 +1115,22 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { _ => crate::unreachable!("Not a valid facet for a simple type!"), } + if let Some(binary_type) = processor.binary_type.clone() { + constrains.binary_type = Some(binary_type); + } + Ok(()) }) } + fn resolve_binary_type(&self, ident: &TypeIdent) -> Option { + match ident.name.as_str() { + "hexBinary" => Some(BinaryType::Hex), + "base64Binary" => Some(BinaryType::Base64), + _ => self.owner.get_type(ident).binary_type.clone(), + } + } + #[instrument(err, level = "trace", skip(self))] fn apply_enumeration(&mut self, ty: &'schema FacetType) -> Result<(), Error> { let name = Name::from(ty.value.trim().to_owned()); @@ -1252,6 +1282,10 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { let mut base = base.into_owned(); + if let BaseIdent::Simple(ident) = &ident { + self.binary_type = self.binary_type.clone().or(self.resolve_binary_type(ident)); + } + match (self.content_mode, &mut base) { (ContentMode::Simple, MetaTypeVariant::Enumeration(ei)) => ei.variants.clear(), (ContentMode::Complex, MetaTypeVariant::ComplexType(ci)) => { diff --git a/xsd-parser/src/pipeline/renderer/steps/mod.rs b/xsd-parser/src/pipeline/renderer/steps/mod.rs index cca635c8..1d0c280d 100644 --- a/xsd-parser/src/pipeline/renderer/steps/mod.rs +++ b/xsd-parser/src/pipeline/renderer/steps/mod.rs @@ -18,6 +18,7 @@ use crate::config::RendererFlags; use crate::models::{ code::IdentPath, data::{ConfigValue, ConstrainsData, EnumerationData, SimpleData, UnionData}, + meta::BinaryType, }; use super::Context; @@ -201,6 +202,28 @@ impl ConstrainsData<'_> { let validate_range_end = self.render_validate_range_end(ctx); let validate_min_length = self.render_validate_min_length(ctx); let validate_max_length = self.render_validate_max_length(ctx); + let binary_value_length = self.meta.binary_type.as_ref().map(|binary_type| { + let body = match binary_type { + BinaryType::Hex => quote! { + value.bytes().count() / 2usize + }, + BinaryType::Base64 => quote! { + let bytes = value.as_bytes(); + let padding = match bytes { + [.., b'=', b'='] => 2, + [.., b'='] => 1, + _ => 0, + }; + (bytes.len() / 4usize) * 3usize - padding + }, + }; + + quote! { + fn binary_value_length(value: &str) -> usize { + #body + } + } + }); let result = ctx.resolve_build_in("::core::result::Result"); @@ -209,6 +232,7 @@ impl ConstrainsData<'_> { quote! { pub fn validate_value(value: &#target_type) -> #result<(), #validate_error> { + #binary_value_length #validate_range_start #validate_range_end #validate_min_length @@ -279,6 +303,8 @@ impl ConstrainsData<'_> { let check = if *x == 1 { quote!(value.is_empty()) + } else if self.meta.binary_type.is_some() { + quote!(binary_value_length(value) < #x) } else { quote!(value.len() < #x) }; @@ -298,6 +324,8 @@ impl ConstrainsData<'_> { self.meta.max_length.as_ref().map(|x| { let check = if *x == 0 { quote!(!value.is_empty()) + } else if self.meta.binary_type.is_some() { + quote!(binary_value_length(value) > #x) } else { quote!(value.len() > #x) }; diff --git a/xsd-parser/tests/feature/facets/example/default.xml b/xsd-parser/tests/feature/facets/example/default.xml index 9a33d023..455e2a56 100644 --- a/xsd-parser/tests/feature/facets/example/default.xml +++ b/xsd-parser/tests/feature/facets/example/default.xml @@ -2,4 +2,6 @@ -1234.56 0.01 Abcdef - + a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9 + QUJDREVGR0hJSktMTU5PUA== + \ No newline at end of file diff --git a/xsd-parser/tests/feature/facets/expected/default.rs b/xsd-parser/tests/feature/facets/expected/default.rs index 688e72e1..63da47c6 100644 --- a/xsd-parser/tests/feature/facets/expected/default.rs +++ b/xsd-parser/tests/feature/facets/expected/default.rs @@ -12,6 +12,8 @@ pub enum RootTypeContent { NegativeDecimal(NegativeDecimalType), PositiveDecimal(PositiveDecimalType), RestrictedString(RestrictedStringType), + HexType(HexType), + Base64Type(Base64Type), } #[derive(Debug)] pub struct NegativeDecimalType(pub f64); @@ -147,3 +149,91 @@ impl Deref for RestrictedStringType { &self.0 } } +#[derive(Debug)] +pub struct HexType(pub String); +impl HexType { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + fn binary_value_length(value: &str) -> usize { + value.bytes().count() / 2usize + } + if binary_value_length(value) < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if binary_value_length(value) > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: HexType) -> String { + value.0 + } +} +impl TryFrom for HexType { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for HexType { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug)] +pub struct Base64Type(pub String); +impl Base64Type { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + fn binary_value_length(value: &str) -> usize { + let bytes = value.as_bytes(); + let padding = match bytes { + [.., b'=', b'='] => 2, + [.., b'='] => 1, + _ => 0, + }; + (bytes.len() / 4usize) * 3usize - padding + } + if binary_value_length(value) < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if binary_value_length(value) > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: Base64Type) -> String { + value.0 + } +} +impl TryFrom for Base64Type { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for Base64Type { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/xsd-parser/tests/feature/facets/expected/quick_xml.rs b/xsd-parser/tests/feature/facets/expected/quick_xml.rs index 5dbd16a0..701a2081 100644 --- a/xsd-parser/tests/feature/facets/expected/quick_xml.rs +++ b/xsd-parser/tests/feature/facets/expected/quick_xml.rs @@ -27,6 +27,8 @@ pub enum RootTypeContent { NegativeDecimal(NegativeDecimalType), PositiveDecimal(PositiveDecimalType), RestrictedString(RestrictedStringType), + HexType(HexType), + Base64Type(Base64Type), } impl WithSerializer for RootType { type Serializer<'x> = quick_xml_serialize::RootTypeSerializer<'x>; @@ -247,6 +249,120 @@ impl DeserializeBytes for RestrictedStringType { } } impl WithDeserializerFromBytes for RestrictedStringType {} +#[derive(Debug)] +pub struct HexType(pub String); +impl HexType { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + fn binary_value_length(value: &str) -> usize { + value.bytes().count() / 2usize + } + if binary_value_length(value) < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if binary_value_length(value) > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: HexType) -> String { + value.0 + } +} +impl TryFrom for HexType { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for HexType { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl SerializeBytes for HexType { + fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { + self.0.serialize_bytes(helper) + } +} +impl WithSerializeToBytes for HexType {} +impl DeserializeBytes for HexType { + fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let inner = String::deserialize_bytes(helper, bytes)?; + Ok(Self::new(inner).map_err(|error| (bytes, error))?) + } +} +impl WithDeserializerFromBytes for HexType {} +#[derive(Debug)] +pub struct Base64Type(pub String); +impl Base64Type { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + fn binary_value_length(value: &str) -> usize { + let bytes = value.as_bytes(); + let padding = match bytes { + [.., b'=', b'='] => 2, + [.., b'='] => 1, + _ => 0, + }; + (bytes.len() / 4usize) * 3usize - padding + } + if binary_value_length(value) < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if binary_value_length(value) > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: Base64Type) -> String { + value.0 + } +} +impl TryFrom for Base64Type { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for Base64Type { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl SerializeBytes for Base64Type { + fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { + self.0.serialize_bytes(helper) + } +} +impl WithSerializeToBytes for Base64Type {} +impl DeserializeBytes for Base64Type { + fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let inner = String::deserialize_bytes(helper, bytes)?; + Ok(Self::new(inner).map_err(|error| (bytes, error))?) + } +} +impl WithDeserializerFromBytes for Base64Type {} pub mod quick_xml_deserialize { use core::mem::replace; use xsd_parser_types::quick_xml::{ @@ -416,6 +532,16 @@ pub mod quick_xml_deserialize { Option<::Deserializer>, Option<::Deserializer>, ), + HexType( + Option, + Option<::Deserializer>, + Option<::Deserializer>, + ), + Base64Type( + Option, + Option<::Deserializer>, + Option<::Deserializer>, + ), Done__(super::RootTypeContent), Unknown__, } @@ -450,6 +576,20 @@ pub mod quick_xml_deserialize { ::init(helper, event)?; return self.handle_restricted_string(helper, Default::default(), None, output); } + if matches!( + helper.resolve_local_name(x.name(), &super::NS_TNS), + Some(b"HexType") + ) { + let output = ::init(helper, event)?; + return self.handle_hex_type(helper, Default::default(), None, output); + } + if matches!( + helper.resolve_local_name(x.name(), &super::NS_TNS), + Some(b"Base64Type") + ) { + let output = ::init(helper, event)?; + return self.handle_base_64_type(helper, Default::default(), None, output); + } } *self.state__ = RootTypeContentDeserializerState::Init__; Ok(ElementHandlerOutput::return_to_parent(event, false)) @@ -488,6 +628,24 @@ pub mod quick_xml_deserialize { helper.finish_element("RestrictedString", values)?, )) } + S::HexType(mut values, None, deserializer) => { + if let Some(deserializer) = deserializer { + let value = deserializer.finish(helper)?; + Self::store_hex_type(&mut values, value)?; + } + Ok(super::RootTypeContent::HexType( + helper.finish_element("HexType", values)?, + )) + } + S::Base64Type(mut values, None, deserializer) => { + if let Some(deserializer) = deserializer { + let value = deserializer.finish(helper)?; + Self::store_base_64_type(&mut values, value)?; + } + Ok(super::RootTypeContent::Base64Type( + helper.finish_element("Base64Type", values)?, + )) + } S::Done__(data) => Ok(data), _ => unreachable!(), } @@ -528,6 +686,30 @@ pub mod quick_xml_deserialize { *values = Some(value); Ok(()) } + fn store_hex_type( + values: &mut Option, + value: super::HexType, + ) -> Result<(), Error> { + if values.is_some() { + Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( + b"HexType", + )))?; + } + *values = Some(value); + Ok(()) + } + fn store_base_64_type( + values: &mut Option, + value: super::Base64Type, + ) -> Result<(), Error> { + if values.is_some() { + Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( + b"Base64Type", + )))?; + } + *values = Some(value); + Ok(()) + } fn handle_negative_decimal<'de>( &mut self, helper: &mut DeserializeHelper, @@ -630,6 +812,74 @@ pub mod quick_xml_deserialize { } } } + fn handle_hex_type<'de>( + &mut self, + helper: &mut DeserializeHelper, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, super::HexType>, + ) -> Result, Error> { + use RootTypeContentDeserializerState as S; + let DeserializerOutput { + artifact, + event, + allow_any, + } = output; + if artifact.is_none() { + return Ok(ElementHandlerOutput::return_to_root(event, allow_any)); + } + if let Some(deserializer) = fallback { + let data = deserializer.finish(helper)?; + Self::store_hex_type(&mut values, data)?; + } + match artifact { + DeserializerArtifact::None => unreachable!(), + DeserializerArtifact::Data(data) => { + Self::store_hex_type(&mut values, data)?; + let data = Self::finish_state(helper, S::HexType(values, None, None))?; + *self.state__ = S::Done__(data); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + DeserializerArtifact::Deserializer(deserializer) => { + *self.state__ = S::HexType(values, None, Some(deserializer)); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + } + } + fn handle_base_64_type<'de>( + &mut self, + helper: &mut DeserializeHelper, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, super::Base64Type>, + ) -> Result, Error> { + use RootTypeContentDeserializerState as S; + let DeserializerOutput { + artifact, + event, + allow_any, + } = output; + if artifact.is_none() { + return Ok(ElementHandlerOutput::return_to_root(event, allow_any)); + } + if let Some(deserializer) = fallback { + let data = deserializer.finish(helper)?; + Self::store_base_64_type(&mut values, data)?; + } + match artifact { + DeserializerArtifact::None => unreachable!(), + DeserializerArtifact::Data(data) => { + Self::store_base_64_type(&mut values, data)?; + let data = Self::finish_state(helper, S::Base64Type(values, None, None))?; + *self.state__ = S::Done__(data); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + DeserializerArtifact::Deserializer(deserializer) => { + *self.state__ = S::Base64Type(values, None, Some(deserializer)); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + } + } } impl<'de> Deserializer<'de, super::RootTypeContent> for RootTypeContentDeserializer { fn init( @@ -688,6 +938,24 @@ pub mod quick_xml_deserialize { ElementHandlerOutput::Continue { event, .. } => event, } } + (S::HexType(values, fallback, Some(deserializer)), event) => { + let output = deserializer.next(helper, event)?; + match self.handle_hex_type(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + (S::Base64Type(values, fallback, Some(deserializer)), event) => { + let output = deserializer.next(helper, event)?; + match self.handle_base_64_type(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } (state, event @ Event::End(_)) => { return Ok(DeserializerOutput { artifact: DeserializerArtifact::Data(Self::finish_state( @@ -754,6 +1022,40 @@ pub mod quick_xml_deserialize { ElementHandlerOutput::Continue { event, .. } => event, } } + ( + S::HexType(values, fallback, None), + event @ (Event::Start(_) | Event::Empty(_)), + ) => { + let output = helper.init_start_tag_deserializer( + event, + Some(&super::NS_TNS), + b"HexType", + false, + )?; + match self.handle_hex_type(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + ( + S::Base64Type(values, fallback, None), + event @ (Event::Start(_) | Event::Empty(_)), + ) => { + let output = helper.init_start_tag_deserializer( + event, + Some(&super::NS_TNS), + b"Base64Type", + false, + )?; + match self.handle_base_64_type(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } (state @ S::Done__(_), event) => { *self.state__ = state; break (DeserializerEvent::Continue(event), false); @@ -858,6 +1160,8 @@ pub mod quick_xml_serialize { NegativeDecimal(::Serializer<'ser>), PositiveDecimal(::Serializer<'ser>), RestrictedString(::Serializer<'ser>), + HexType(::Serializer<'ser>), + Base64Type(::Serializer<'ser>), Done__, Phantom__(&'ser ()), } @@ -884,6 +1188,16 @@ pub mod quick_xml_serialize { WithSerializer::serializer(x, Some("RestrictedString"), false)?, ) } + super::RootTypeContent::HexType(x) => { + *self.state = RootTypeContentSerializerState::HexType( + WithSerializer::serializer(x, Some("HexType"), false)?, + ) + } + super::RootTypeContent::Base64Type(x) => { + *self.state = RootTypeContentSerializerState::Base64Type( + WithSerializer::serializer(x, Some("Base64Type"), false)?, + ) + } }, RootTypeContentSerializerState::NegativeDecimal(x) => { match x.next(helper).transpose()? { @@ -903,6 +1217,18 @@ pub mod quick_xml_serialize { None => *self.state = RootTypeContentSerializerState::Done__, } } + RootTypeContentSerializerState::HexType(x) => { + match x.next(helper).transpose()? { + Some(event) => return Ok(Some(event)), + None => *self.state = RootTypeContentSerializerState::Done__, + } + } + RootTypeContentSerializerState::Base64Type(x) => { + match x.next(helper).transpose()? { + Some(event) => return Ok(Some(event)), + None => *self.state = RootTypeContentSerializerState::Done__, + } + } RootTypeContentSerializerState::Done__ => return Ok(None), RootTypeContentSerializerState::Phantom__(_) => unreachable!(), } diff --git a/xsd-parser/tests/feature/facets/expected/serde_quick_xml.rs b/xsd-parser/tests/feature/facets/expected/serde_quick_xml.rs index f017e821..5ca25505 100644 --- a/xsd-parser/tests/feature/facets/expected/serde_quick_xml.rs +++ b/xsd-parser/tests/feature/facets/expected/serde_quick_xml.rs @@ -17,6 +17,10 @@ pub enum RootTypeContent { PositiveDecimal(PositiveDecimalType), #[serde(rename = "RestrictedString")] RestrictedString(RestrictedStringType), + #[serde(rename = "HexType")] + HexType(HexType), + #[serde(rename = "Base64Type")] + Base64Type(Base64Type), } #[derive(Debug, Deserialize, Serialize)] pub struct NegativeDecimalType(pub f64); @@ -152,3 +156,91 @@ impl Deref for RestrictedStringType { &self.0 } } +#[derive(Debug, Deserialize, Serialize)] +pub struct HexType(pub String); +impl HexType { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + fn binary_value_length(value: &str) -> usize { + value.bytes().count() / 2usize + } + if binary_value_length(value) < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if binary_value_length(value) > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: HexType) -> String { + value.0 + } +} +impl TryFrom for HexType { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for HexType { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct Base64Type(pub String); +impl Base64Type { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + fn binary_value_length(value: &str) -> usize { + let bytes = value.as_bytes(); + let padding = match bytes { + [.., b'=', b'='] => 2, + [.., b'='] => 1, + _ => 0, + }; + (bytes.len() / 4usize) * 3usize - padding + } + if binary_value_length(value) < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if binary_value_length(value) > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: Base64Type) -> String { + value.0 + } +} +impl TryFrom for Base64Type { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for Base64Type { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/xsd-parser/tests/feature/facets/expected/serde_xml_rs.rs b/xsd-parser/tests/feature/facets/expected/serde_xml_rs.rs index 5a004438..0875ef42 100644 --- a/xsd-parser/tests/feature/facets/expected/serde_xml_rs.rs +++ b/xsd-parser/tests/feature/facets/expected/serde_xml_rs.rs @@ -17,6 +17,10 @@ pub enum RootTypeContent { PositiveDecimal(PositiveDecimalType), #[serde(rename = "RestrictedString")] RestrictedString(RestrictedStringType), + #[serde(rename = "HexType")] + HexType(HexType), + #[serde(rename = "Base64Type")] + Base64Type(Base64Type), } #[derive(Debug, Deserialize, Serialize)] pub struct NegativeDecimalType(pub f64); @@ -152,3 +156,91 @@ impl Deref for RestrictedStringType { &self.0 } } +#[derive(Debug, Deserialize, Serialize)] +pub struct HexType(pub String); +impl HexType { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + fn binary_value_length(value: &str) -> usize { + value.bytes().count() / 2usize + } + if binary_value_length(value) < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if binary_value_length(value) > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: HexType) -> String { + value.0 + } +} +impl TryFrom for HexType { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for HexType { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct Base64Type(pub String); +impl Base64Type { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + fn binary_value_length(value: &str) -> usize { + let bytes = value.as_bytes(); + let padding = match bytes { + [.., b'=', b'='] => 2, + [.., b'='] => 1, + _ => 0, + }; + (bytes.len() / 4usize) * 3usize - padding + } + if binary_value_length(value) < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if binary_value_length(value) > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: Base64Type) -> String { + value.0 + } +} +impl TryFrom for Base64Type { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for Base64Type { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/xsd-parser/tests/feature/facets/mod.rs b/xsd-parser/tests/feature/facets/mod.rs index 3a55d60e..89bdde7e 100644 --- a/xsd-parser/tests/feature/facets/mod.rs +++ b/xsd-parser/tests/feature/facets/mod.rs @@ -22,6 +22,8 @@ macro_rules! check_obj { assert!(matches!(it.next(), Some(RootTypeContent::NegativeDecimal(x)) if x.eq(&-1234.56_f64))); assert!(matches!(it.next(), Some(RootTypeContent::PositiveDecimal(x)) if x.eq(&0.01_f64))); assert!(matches!(it.next(), Some(RootTypeContent::RestrictedString(x)) if *x == "Abcdef")); + assert!(matches!(it.next(), Some(RootTypeContent::HexType(x)) if *x == "a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9")); + assert!(matches!(it.next(), Some(RootTypeContent::Base64Type(x)) if *x == "QUJDREVGR0hJSktMTU5PUA==")); assert!(it.next().is_none()); }}; } @@ -36,6 +38,14 @@ macro_rules! test_obj { RootTypeContent::NegativeDecimal((-1234.56_f64).try_into().unwrap()), RootTypeContent::PositiveDecimal(0.011_f64.try_into().unwrap()), RootTypeContent::RestrictedString(String::from("Abcdef").try_into().unwrap()), + RootTypeContent::HexType( + String::from("a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9") + .try_into() + .unwrap(), + ), + RootTypeContent::Base64Type( + String::from("QUJDREVGR0hJSktMTU5PUA==").try_into().unwrap(), + ), ], } }}; diff --git a/xsd-parser/tests/feature/facets/schema.xsd b/xsd-parser/tests/feature/facets/schema.xsd index 0ea81f18..84d76c93 100644 --- a/xsd-parser/tests/feature/facets/schema.xsd +++ b/xsd-parser/tests/feature/facets/schema.xsd @@ -1,8 +1,8 @@ + xmlns:tns="http://example.com" + targetNamespace="http://example.com" + elementFormDefault="unqualified"> @@ -29,12 +29,26 @@ + + + + + + + + + + + + - - - + + + + + From b645c44fd05b8453906d600a04a525378ec26dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Oliveira?= Date: Thu, 16 Apr 2026 03:40:36 +0100 Subject: [PATCH 2/7] Revert previous commit and try new approach --- xsd-parser-types/src/xml/base64binary.rs | 81 +++++++++++++++++++ xsd-parser-types/src/xml/hexbinary.rs | 80 ++++++++++++++++++ xsd-parser-types/src/xml/mod.rs | 5 ++ xsd-parser/src/config/mod.rs | 34 ++++++++ xsd-parser/src/models/meta/mod.rs | 14 ---- xsd-parser/src/models/meta/type_.rs | 8 +- .../state/generate_types/variant_processor.rs | 42 +--------- xsd-parser/src/pipeline/renderer/steps/mod.rs | 28 ------- .../tests/feature/facets/expected/default.rs | 61 ++++++-------- .../feature/facets/expected/quick_xml.rs | 61 ++++++-------- .../facets/expected/serde_quick_xml.rs | 61 ++++++-------- .../feature/facets/expected/serde_xml_rs.rs | 61 ++++++-------- xsd-parser/tests/feature/facets/mod.rs | 23 +++--- 13 files changed, 321 insertions(+), 238 deletions(-) create mode 100644 xsd-parser-types/src/xml/base64binary.rs create mode 100644 xsd-parser-types/src/xml/hexbinary.rs diff --git a/xsd-parser-types/src/xml/base64binary.rs b/xsd-parser-types/src/xml/base64binary.rs new file mode 100644 index 00000000..12a0183d --- /dev/null +++ b/xsd-parser-types/src/xml/base64binary.rs @@ -0,0 +1,81 @@ +use std::borrow::Cow; +use std::ops::Deref; + +#[cfg(feature = "quick-xml")] +use crate::quick_xml::{ + DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, +}; + +/// Wrapper for base64Binary encoded as a String. +#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Base64String(pub String); + +impl Base64String { + /// Returns the byte length of the decoded data, not the length of the string. + #[must_use] + pub fn len(&self) -> usize { + let bytes = self.0.trim_end_matches('='); + bytes.len() * 3 / 4 + } + + /// Check emptyness + #[must_use] + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Get the inner string as a &str. + #[must_use] + pub fn as_str(&self) -> &str { + self.0.as_str() + } +} + +impl From for Base64String { + fn from(value: String) -> Self { + Self(value) + } +} + +impl From for String { + fn from(value: Base64String) -> Self { + value.0 + } +} + +impl Deref for Base64String { + type Target = String; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[cfg(feature = "quick-xml")] +impl SerializeBytes for Base64String { + fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { + self.0.serialize_bytes(helper) + } +} + +#[cfg(feature = "quick-xml")] +impl DeserializeBytes for Base64String { + fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let inner = String::deserialize_bytes(helper, bytes)?; + Ok(Self(inner)) + } +} + +/// Wrapper for base64Binary as decoded bytes. +#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Base64Binary(pub Vec); + +impl Deref for Base64Binary { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/xsd-parser-types/src/xml/hexbinary.rs b/xsd-parser-types/src/xml/hexbinary.rs new file mode 100644 index 00000000..131ee655 --- /dev/null +++ b/xsd-parser-types/src/xml/hexbinary.rs @@ -0,0 +1,80 @@ +use std::borrow::Cow; +use std::ops::Deref; + +#[cfg(feature = "quick-xml")] +use crate::quick_xml::{ + DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, +}; + +/// Wrapper for hexBinary encoded as String. +#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct HexString(pub String); + +impl HexString { + /// Returns the byte length of the decoded data, and not the length of the string. + #[must_use] + pub fn len(&self) -> usize { + self.0.len() / 2 + } + + /// Check emptyness + #[must_use] + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Get the inner string as a &str. + #[must_use] + pub fn as_str(&self) -> &str { + self.0.as_str() + } +} + +impl From for HexString { + fn from(value: String) -> Self { + Self(value) + } +} + +impl From for String { + fn from(value: HexString) -> Self { + value.0 + } +} + +impl Deref for HexString { + type Target = String; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[cfg(feature = "quick-xml")] +impl SerializeBytes for HexString { + fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { + self.0.serialize_bytes(helper) + } +} + +#[cfg(feature = "quick-xml")] +impl DeserializeBytes for HexString { + fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let inner = String::deserialize_bytes(helper, bytes)?; + Ok(Self(inner)) + } +} + +/// Wrapper for hexBinary as decoded bytes. +#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct HexBinary(pub Vec); + +impl Deref for HexBinary { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/xsd-parser-types/src/xml/mod.rs b/xsd-parser-types/src/xml/mod.rs index eede8ba1..aaa95632 100644 --- a/xsd-parser-types/src/xml/mod.rs +++ b/xsd-parser-types/src/xml/mod.rs @@ -4,7 +4,9 @@ mod any_simple_type; mod attributes; +mod base64binary; mod element; +mod hexbinary; mod mixed; mod namespace_scope; mod namespaces; @@ -13,6 +15,9 @@ mod qname; mod text; mod value; +pub use self::base64binary::{Base64Binary as Base64BinaryBytes, Base64String}; +pub use self::hexbinary::{HexBinary, HexString}; + pub use self::any_simple_type::{AnySimpleType, Base64Binary, Decimal, Integer, Unsigned}; pub use self::attributes::{ AnyAttributes, Attributes, Key as AttributeKey, Value as AttributeValue, diff --git a/xsd-parser/src/config/mod.rs b/xsd-parser/src/config/mod.rs index cbc3c736..efbe5f53 100644 --- a/xsd-parser/src/config/mod.rs +++ b/xsd-parser/src/config/mod.rs @@ -541,6 +541,40 @@ impl Config { self.with_type(ident, meta) } + /// Add a type definition for `xs:hexBinary` that uses the `xsd_parser_types::xml::HexBinary` type.. + pub fn with_hexbinary_type(self) -> Self { + self.with_hexbinary_type_from("::xsd_parser_types::xml::HexBinary") + } + + /// Add a type definition for `xs:hexBinary` that uses the type defined at the passed `path`. + pub fn with_hexbinary_type_from(self, path: &str) -> Self { + let name = path.rsplit_once("::").map_or(path, |(_, name)| name); + + let ident = (IdentType::Type, Namespace::XS, "hexBinary"); + let meta = CustomMeta::new(name) + .include_from(path) + .with_namespace(Namespace::XS); + + self.with_type(ident, meta) + } + + /// Add a type definition for `xs:base64Binary` that uses the `xsd_parser_types::xml::Base64Binary` type. + pub fn with_base64binary_type(self) -> Self { + self.with_base64binary_type_from("::xsd_parser_types::xml::Base64BinaryBytes") + } + + /// Add a type definition for `xs:Base64Binary` that uses the type defined at the passed `path`. + pub fn with_base64binary_type_from(self, path: &str) -> Self { + let name = path.rsplit_once("::").map_or(path, |(_, name)| name); + + let ident = (IdentType::Type, Namespace::XS, "base64Binary"); + let meta = CustomMeta::new(name) + .include_from(path) + .with_namespace(Namespace::XS); + + self.with_type(ident, meta) + } + /// Set the postfix that should be applied to the name of types. /// /// For details please refer to [`GeneratorConfig::type_postfix`]. diff --git a/xsd-parser/src/models/meta/mod.rs b/xsd-parser/src/models/meta/mod.rs index cec5f7aa..3c6cb43f 100644 --- a/xsd-parser/src/models/meta/mod.rs +++ b/xsd-parser/src/models/meta/mod.rs @@ -35,16 +35,6 @@ pub use self::type_eq::TypeEq; pub use self::types::{MetaTypes, ModuleMeta, SchemaMeta}; pub use self::union::{UnionMeta, UnionMetaType, UnionMetaTypes}; -/// Indicate what type of binary value is expected -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum BinaryType { - /// Value is based on `xs:hexBinary`. - Hex, - - /// Value is based on `xs:base64Binary`. - Base64, -} - /// Constrains defined by the different facets of a type. #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct Constrains { @@ -68,9 +58,6 @@ pub struct Constrains { /// Defines the whitespace handling. pub whitespace: WhiteSpace, - - /// Indicates if the value is a binary primitive and which lexical rules it uses. - pub binary_type: Option, } impl Default for Constrains { @@ -86,7 +73,6 @@ impl Default for Constrains { min_length: None, max_length: None, whitespace: WhiteSpace::default(), - binary_type: None, } } } diff --git a/xsd-parser/src/models/meta/type_.rs b/xsd-parser/src/models/meta/type_.rs index 677b28fb..346ecbcc 100644 --- a/xsd-parser/src/models/meta/type_.rs +++ b/xsd-parser/src/models/meta/type_.rs @@ -11,8 +11,8 @@ use crate::models::schema::{xs::FormChoiceType, SchemaId}; use crate::models::TypeIdent; use super::{ - BinaryType, ComplexMeta, CustomMeta, DynamicMeta, EnumerationMeta, GroupMeta, MetaTypes, - ReferenceMeta, SimpleMeta, TypeEq, UnionMeta, + ComplexMeta, CustomMeta, DynamicMeta, EnumerationMeta, GroupMeta, MetaTypes, ReferenceMeta, + SimpleMeta, TypeEq, UnionMeta, }; /// Represents a fully interpreted type from an XML schema. @@ -39,9 +39,6 @@ pub struct MetaType { /// Documentation of the type extracted from `xs:documentation` nodes. pub documentation: Vec, - - /// Indicates if and what type of Binary is this type. - pub binary_type: Option, } /// Actual data variant a [`MetaType`] represents. @@ -134,7 +131,6 @@ impl MetaType { pub fn new(variant: MetaTypeVariant) -> Self { Self { variant, - binary_type: None, form: None, schema: None, display_name: None, diff --git a/xsd-parser/src/pipeline/interpreter/state/generate_types/variant_processor.rs b/xsd-parser/src/pipeline/interpreter/state/generate_types/variant_processor.rs index 42178c7a..c19841c5 100644 --- a/xsd-parser/src/pipeline/interpreter/state/generate_types/variant_processor.rs +++ b/xsd-parser/src/pipeline/interpreter/state/generate_types/variant_processor.rs @@ -6,8 +6,8 @@ use std::str::from_utf8; use tracing::instrument; use crate::models::meta::{ - AnyAttributeMeta, AnyMeta, AttributeMeta, Base, BinaryType, DerivedTypeMeta, DynamicMeta, - ElementMeta, ElementMetaVariant, ElementMode, ElementsMeta, EnumerationMetaVariant, MetaType, + AnyAttributeMeta, AnyMeta, AttributeMeta, Base, DerivedTypeMeta, DynamicMeta, ElementMeta, + ElementMetaVariant, ElementMode, ElementsMeta, EnumerationMetaVariant, MetaType, MetaTypeVariant, ReferenceMeta, SimpleMeta, UnionMetaType, WhiteSpace, }; use crate::models::schema::xs::{ @@ -44,9 +44,6 @@ pub(super) struct VariantProcessor<'a, 'state, 'schema> { /// and `xs:documentation` nodes. documentation: Vec, - /// If the type is either based on `xs:hexBinary` or `xs:base64Binary`, indicate which of the two - binary_type: Option, - /// `true` if the simple content type of a complex type was already duplicated /// and is now unique for this type. is_simple_content_unique: bool, @@ -162,26 +159,18 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { type_mode: TypeMode::Unknown, content_mode: ContentMode::Unknown, documentation: Vec::new(), - binary_type: None, is_simple_content_unique: false, } } pub(super) fn finish(self) -> Result { - let Self { - variant, - owner, - documentation, - binary_type, - .. - } = self; + let Self { variant, owner, .. } = self; let variant = variant.ok_or(Error::NoType)?; let mut type_ = MetaType::new(variant); - type_.binary_type = binary_type; type_.form = Some(owner.current_schema().element_form_default); type_.schema = Some(owner.current_schema_id()); - type_.documentation = documentation; + type_.documentation = self.documentation; Ok(type_) } @@ -190,7 +179,6 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { let variant = self.variant.take().ok_or(Error::NoType)?; let mut type_ = MetaType::new(variant); - type_.binary_type = self.binary_type.clone(); type_.form = Some(self.owner.current_schema().element_form_default); type_.schema = Some(self.owner.current_schema_id()); swap(&mut type_.documentation, &mut self.documentation); @@ -205,7 +193,6 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { self.fixed = false; self.type_mode = TypeMode::Unknown; self.content_mode = ContentMode::Unknown; - self.binary_type = None; self.is_simple_content_unique = false; self.documentation.clear(); @@ -429,7 +416,6 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { .map(|base| { let base = self.owner.resolve_type_ident(base, IdentType::Type)?; - self.binary_type = self.resolve_binary_type(&base); self.copy_base_type(base, UpdateMode::Restriction) }) .transpose()?; @@ -603,10 +589,6 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { fn apply_restriction(&mut self, ty: &'schema RestrictionType) -> Result<(), Error> { use crate::models::schema::xs::RestrictionTypeContent as C; - let base = self.owner.resolve_type_ident(&ty.base, IdentType::Type)?; - let binary_type = self.resolve_binary_type(&base); - self.binary_type = binary_type; - for c in &ty.content { match c { C::OpenContent(_) | C::Assert(_) => (), @@ -1115,22 +1097,10 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { _ => crate::unreachable!("Not a valid facet for a simple type!"), } - if let Some(binary_type) = processor.binary_type.clone() { - constrains.binary_type = Some(binary_type); - } - Ok(()) }) } - fn resolve_binary_type(&self, ident: &TypeIdent) -> Option { - match ident.name.as_str() { - "hexBinary" => Some(BinaryType::Hex), - "base64Binary" => Some(BinaryType::Base64), - _ => self.owner.get_type(ident).binary_type.clone(), - } - } - #[instrument(err, level = "trace", skip(self))] fn apply_enumeration(&mut self, ty: &'schema FacetType) -> Result<(), Error> { let name = Name::from(ty.value.trim().to_owned()); @@ -1282,10 +1252,6 @@ impl<'a, 'state, 'schema> VariantProcessor<'a, 'state, 'schema> { let mut base = base.into_owned(); - if let BaseIdent::Simple(ident) = &ident { - self.binary_type = self.binary_type.clone().or(self.resolve_binary_type(ident)); - } - match (self.content_mode, &mut base) { (ContentMode::Simple, MetaTypeVariant::Enumeration(ei)) => ei.variants.clear(), (ContentMode::Complex, MetaTypeVariant::ComplexType(ci)) => { diff --git a/xsd-parser/src/pipeline/renderer/steps/mod.rs b/xsd-parser/src/pipeline/renderer/steps/mod.rs index 1d0c280d..cca635c8 100644 --- a/xsd-parser/src/pipeline/renderer/steps/mod.rs +++ b/xsd-parser/src/pipeline/renderer/steps/mod.rs @@ -18,7 +18,6 @@ use crate::config::RendererFlags; use crate::models::{ code::IdentPath, data::{ConfigValue, ConstrainsData, EnumerationData, SimpleData, UnionData}, - meta::BinaryType, }; use super::Context; @@ -202,28 +201,6 @@ impl ConstrainsData<'_> { let validate_range_end = self.render_validate_range_end(ctx); let validate_min_length = self.render_validate_min_length(ctx); let validate_max_length = self.render_validate_max_length(ctx); - let binary_value_length = self.meta.binary_type.as_ref().map(|binary_type| { - let body = match binary_type { - BinaryType::Hex => quote! { - value.bytes().count() / 2usize - }, - BinaryType::Base64 => quote! { - let bytes = value.as_bytes(); - let padding = match bytes { - [.., b'=', b'='] => 2, - [.., b'='] => 1, - _ => 0, - }; - (bytes.len() / 4usize) * 3usize - padding - }, - }; - - quote! { - fn binary_value_length(value: &str) -> usize { - #body - } - } - }); let result = ctx.resolve_build_in("::core::result::Result"); @@ -232,7 +209,6 @@ impl ConstrainsData<'_> { quote! { pub fn validate_value(value: &#target_type) -> #result<(), #validate_error> { - #binary_value_length #validate_range_start #validate_range_end #validate_min_length @@ -303,8 +279,6 @@ impl ConstrainsData<'_> { let check = if *x == 1 { quote!(value.is_empty()) - } else if self.meta.binary_type.is_some() { - quote!(binary_value_length(value) < #x) } else { quote!(value.len() < #x) }; @@ -324,8 +298,6 @@ impl ConstrainsData<'_> { self.meta.max_length.as_ref().map(|x| { let check = if *x == 0 { quote!(!value.is_empty()) - } else if self.meta.binary_type.is_some() { - quote!(binary_value_length(value) > #x) } else { quote!(value.len() > #x) }; diff --git a/xsd-parser/tests/feature/facets/expected/default.rs b/xsd-parser/tests/feature/facets/expected/default.rs index 63da47c6..5b15d271 100644 --- a/xsd-parser/tests/feature/facets/expected/default.rs +++ b/xsd-parser/tests/feature/facets/expected/default.rs @@ -1,7 +1,10 @@ use core::ops::Deref; use regex::Regex; use std::sync::LazyLock; -use xsd_parser_types::quick_xml::{fraction_digits, ValidateError}; +use xsd_parser_types::{ + quick_xml::{fraction_digits, ValidateError}, + xml::{Base64String, HexString}, +}; pub type Root = RootType; #[derive(Debug)] pub struct RootType { @@ -150,89 +153,77 @@ impl Deref for RestrictedStringType { } } #[derive(Debug)] -pub struct HexType(pub String); +pub struct HexType(pub HexString); impl HexType { - pub fn new(inner: String) -> Result { + pub fn new(inner: HexString) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> String { + pub fn into_inner(self) -> HexString { self.0 } - pub fn validate_value(value: &String) -> Result<(), ValidateError> { - fn binary_value_length(value: &str) -> usize { - value.bytes().count() / 2usize - } - if binary_value_length(value) < 16usize { + pub fn validate_value(value: &HexString) -> Result<(), ValidateError> { + if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } - if binary_value_length(value) > 16usize { + if value.len() > 16usize { return Err(ValidateError::MaxLength(16usize)); } Ok(()) } } -impl From for String { - fn from(value: HexType) -> String { +impl From for HexString { + fn from(value: HexType) -> HexString { value.0 } } -impl TryFrom for HexType { +impl TryFrom for HexType { type Error = ValidateError; - fn try_from(value: String) -> Result { + fn try_from(value: HexString) -> Result { Self::new(value) } } impl Deref for HexType { - type Target = String; + type Target = HexString; fn deref(&self) -> &Self::Target { &self.0 } } #[derive(Debug)] -pub struct Base64Type(pub String); +pub struct Base64Type(pub Base64String); impl Base64Type { - pub fn new(inner: String) -> Result { + pub fn new(inner: Base64String) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> String { + pub fn into_inner(self) -> Base64String { self.0 } - pub fn validate_value(value: &String) -> Result<(), ValidateError> { - fn binary_value_length(value: &str) -> usize { - let bytes = value.as_bytes(); - let padding = match bytes { - [.., b'=', b'='] => 2, - [.., b'='] => 1, - _ => 0, - }; - (bytes.len() / 4usize) * 3usize - padding - } - if binary_value_length(value) < 16usize { + pub fn validate_value(value: &Base64String) -> Result<(), ValidateError> { + if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } - if binary_value_length(value) > 16usize { + if value.len() > 16usize { return Err(ValidateError::MaxLength(16usize)); } Ok(()) } } -impl From for String { - fn from(value: Base64Type) -> String { +impl From for Base64String { + fn from(value: Base64Type) -> Base64String { value.0 } } -impl TryFrom for Base64Type { +impl TryFrom for Base64Type { type Error = ValidateError; - fn try_from(value: String) -> Result { + fn try_from(value: Base64String) -> Result { Self::new(value) } } impl Deref for Base64Type { - type Target = String; + type Target = Base64String; fn deref(&self) -> &Self::Target { &self.0 } diff --git a/xsd-parser/tests/feature/facets/expected/quick_xml.rs b/xsd-parser/tests/feature/facets/expected/quick_xml.rs index 701a2081..15e11c3d 100644 --- a/xsd-parser/tests/feature/facets/expected/quick_xml.rs +++ b/xsd-parser/tests/feature/facets/expected/quick_xml.rs @@ -8,6 +8,7 @@ use xsd_parser_types::{ SerializeBytes, SerializeHelper, ValidateError, WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, WithSerializer, }, + xml::{Base64String, HexString}, }; pub const NS_XS: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema"); pub const NS_XML: Namespace = Namespace::new_const(b"http://www.w3.org/XML/1998/namespace"); @@ -250,42 +251,39 @@ impl DeserializeBytes for RestrictedStringType { } impl WithDeserializerFromBytes for RestrictedStringType {} #[derive(Debug)] -pub struct HexType(pub String); +pub struct HexType(pub HexString); impl HexType { - pub fn new(inner: String) -> Result { + pub fn new(inner: HexString) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> String { + pub fn into_inner(self) -> HexString { self.0 } - pub fn validate_value(value: &String) -> Result<(), ValidateError> { - fn binary_value_length(value: &str) -> usize { - value.bytes().count() / 2usize - } - if binary_value_length(value) < 16usize { + pub fn validate_value(value: &HexString) -> Result<(), ValidateError> { + if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } - if binary_value_length(value) > 16usize { + if value.len() > 16usize { return Err(ValidateError::MaxLength(16usize)); } Ok(()) } } -impl From for String { - fn from(value: HexType) -> String { +impl From for HexString { + fn from(value: HexType) -> HexString { value.0 } } -impl TryFrom for HexType { +impl TryFrom for HexType { type Error = ValidateError; - fn try_from(value: String) -> Result { + fn try_from(value: HexString) -> Result { Self::new(value) } } impl Deref for HexType { - type Target = String; + type Target = HexString; fn deref(&self) -> &Self::Target { &self.0 } @@ -298,54 +296,45 @@ impl SerializeBytes for HexType { impl WithSerializeToBytes for HexType {} impl DeserializeBytes for HexType { fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { - let inner = String::deserialize_bytes(helper, bytes)?; + let inner = HexString::deserialize_bytes(helper, bytes)?; Ok(Self::new(inner).map_err(|error| (bytes, error))?) } } impl WithDeserializerFromBytes for HexType {} #[derive(Debug)] -pub struct Base64Type(pub String); +pub struct Base64Type(pub Base64String); impl Base64Type { - pub fn new(inner: String) -> Result { + pub fn new(inner: Base64String) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> String { + pub fn into_inner(self) -> Base64String { self.0 } - pub fn validate_value(value: &String) -> Result<(), ValidateError> { - fn binary_value_length(value: &str) -> usize { - let bytes = value.as_bytes(); - let padding = match bytes { - [.., b'=', b'='] => 2, - [.., b'='] => 1, - _ => 0, - }; - (bytes.len() / 4usize) * 3usize - padding - } - if binary_value_length(value) < 16usize { + pub fn validate_value(value: &Base64String) -> Result<(), ValidateError> { + if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } - if binary_value_length(value) > 16usize { + if value.len() > 16usize { return Err(ValidateError::MaxLength(16usize)); } Ok(()) } } -impl From for String { - fn from(value: Base64Type) -> String { +impl From for Base64String { + fn from(value: Base64Type) -> Base64String { value.0 } } -impl TryFrom for Base64Type { +impl TryFrom for Base64Type { type Error = ValidateError; - fn try_from(value: String) -> Result { + fn try_from(value: Base64String) -> Result { Self::new(value) } } impl Deref for Base64Type { - type Target = String; + type Target = Base64String; fn deref(&self) -> &Self::Target { &self.0 } @@ -358,7 +347,7 @@ impl SerializeBytes for Base64Type { impl WithSerializeToBytes for Base64Type {} impl DeserializeBytes for Base64Type { fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { - let inner = String::deserialize_bytes(helper, bytes)?; + let inner = Base64String::deserialize_bytes(helper, bytes)?; Ok(Self::new(inner).map_err(|error| (bytes, error))?) } } diff --git a/xsd-parser/tests/feature/facets/expected/serde_quick_xml.rs b/xsd-parser/tests/feature/facets/expected/serde_quick_xml.rs index 5ca25505..c3f7e72b 100644 --- a/xsd-parser/tests/feature/facets/expected/serde_quick_xml.rs +++ b/xsd-parser/tests/feature/facets/expected/serde_quick_xml.rs @@ -2,7 +2,10 @@ use core::ops::Deref; use regex::Regex; use serde::{Deserialize, Serialize}; use std::sync::LazyLock; -use xsd_parser_types::quick_xml::{fraction_digits, ValidateError}; +use xsd_parser_types::{ + quick_xml::{fraction_digits, ValidateError}, + xml::{Base64String, HexString}, +}; pub type Root = RootType; #[derive(Debug, Deserialize, Serialize)] pub struct RootType { @@ -157,89 +160,77 @@ impl Deref for RestrictedStringType { } } #[derive(Debug, Deserialize, Serialize)] -pub struct HexType(pub String); +pub struct HexType(pub HexString); impl HexType { - pub fn new(inner: String) -> Result { + pub fn new(inner: HexString) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> String { + pub fn into_inner(self) -> HexString { self.0 } - pub fn validate_value(value: &String) -> Result<(), ValidateError> { - fn binary_value_length(value: &str) -> usize { - value.bytes().count() / 2usize - } - if binary_value_length(value) < 16usize { + pub fn validate_value(value: &HexString) -> Result<(), ValidateError> { + if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } - if binary_value_length(value) > 16usize { + if value.len() > 16usize { return Err(ValidateError::MaxLength(16usize)); } Ok(()) } } -impl From for String { - fn from(value: HexType) -> String { +impl From for HexString { + fn from(value: HexType) -> HexString { value.0 } } -impl TryFrom for HexType { +impl TryFrom for HexType { type Error = ValidateError; - fn try_from(value: String) -> Result { + fn try_from(value: HexString) -> Result { Self::new(value) } } impl Deref for HexType { - type Target = String; + type Target = HexString; fn deref(&self) -> &Self::Target { &self.0 } } #[derive(Debug, Deserialize, Serialize)] -pub struct Base64Type(pub String); +pub struct Base64Type(pub Base64String); impl Base64Type { - pub fn new(inner: String) -> Result { + pub fn new(inner: Base64String) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> String { + pub fn into_inner(self) -> Base64String { self.0 } - pub fn validate_value(value: &String) -> Result<(), ValidateError> { - fn binary_value_length(value: &str) -> usize { - let bytes = value.as_bytes(); - let padding = match bytes { - [.., b'=', b'='] => 2, - [.., b'='] => 1, - _ => 0, - }; - (bytes.len() / 4usize) * 3usize - padding - } - if binary_value_length(value) < 16usize { + pub fn validate_value(value: &Base64String) -> Result<(), ValidateError> { + if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } - if binary_value_length(value) > 16usize { + if value.len() > 16usize { return Err(ValidateError::MaxLength(16usize)); } Ok(()) } } -impl From for String { - fn from(value: Base64Type) -> String { +impl From for Base64String { + fn from(value: Base64Type) -> Base64String { value.0 } } -impl TryFrom for Base64Type { +impl TryFrom for Base64Type { type Error = ValidateError; - fn try_from(value: String) -> Result { + fn try_from(value: Base64String) -> Result { Self::new(value) } } impl Deref for Base64Type { - type Target = String; + type Target = Base64String; fn deref(&self) -> &Self::Target { &self.0 } diff --git a/xsd-parser/tests/feature/facets/expected/serde_xml_rs.rs b/xsd-parser/tests/feature/facets/expected/serde_xml_rs.rs index 0875ef42..fe815965 100644 --- a/xsd-parser/tests/feature/facets/expected/serde_xml_rs.rs +++ b/xsd-parser/tests/feature/facets/expected/serde_xml_rs.rs @@ -2,7 +2,10 @@ use core::ops::Deref; use regex::Regex; use serde::{Deserialize, Serialize}; use std::sync::LazyLock; -use xsd_parser_types::quick_xml::{fraction_digits, ValidateError}; +use xsd_parser_types::{ + quick_xml::{fraction_digits, ValidateError}, + xml::{Base64String, HexString}, +}; pub type Root = RootType; #[derive(Debug, Deserialize, Serialize)] pub struct RootType { @@ -157,89 +160,77 @@ impl Deref for RestrictedStringType { } } #[derive(Debug, Deserialize, Serialize)] -pub struct HexType(pub String); +pub struct HexType(pub HexString); impl HexType { - pub fn new(inner: String) -> Result { + pub fn new(inner: HexString) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> String { + pub fn into_inner(self) -> HexString { self.0 } - pub fn validate_value(value: &String) -> Result<(), ValidateError> { - fn binary_value_length(value: &str) -> usize { - value.bytes().count() / 2usize - } - if binary_value_length(value) < 16usize { + pub fn validate_value(value: &HexString) -> Result<(), ValidateError> { + if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } - if binary_value_length(value) > 16usize { + if value.len() > 16usize { return Err(ValidateError::MaxLength(16usize)); } Ok(()) } } -impl From for String { - fn from(value: HexType) -> String { +impl From for HexString { + fn from(value: HexType) -> HexString { value.0 } } -impl TryFrom for HexType { +impl TryFrom for HexType { type Error = ValidateError; - fn try_from(value: String) -> Result { + fn try_from(value: HexString) -> Result { Self::new(value) } } impl Deref for HexType { - type Target = String; + type Target = HexString; fn deref(&self) -> &Self::Target { &self.0 } } #[derive(Debug, Deserialize, Serialize)] -pub struct Base64Type(pub String); +pub struct Base64Type(pub Base64String); impl Base64Type { - pub fn new(inner: String) -> Result { + pub fn new(inner: Base64String) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> String { + pub fn into_inner(self) -> Base64String { self.0 } - pub fn validate_value(value: &String) -> Result<(), ValidateError> { - fn binary_value_length(value: &str) -> usize { - let bytes = value.as_bytes(); - let padding = match bytes { - [.., b'=', b'='] => 2, - [.., b'='] => 1, - _ => 0, - }; - (bytes.len() / 4usize) * 3usize - padding - } - if binary_value_length(value) < 16usize { + pub fn validate_value(value: &Base64String) -> Result<(), ValidateError> { + if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } - if binary_value_length(value) > 16usize { + if value.len() > 16usize { return Err(ValidateError::MaxLength(16usize)); } Ok(()) } } -impl From for String { - fn from(value: Base64Type) -> String { +impl From for Base64String { + fn from(value: Base64Type) -> Base64String { value.0 } } -impl TryFrom for Base64Type { +impl TryFrom for Base64Type { type Error = ValidateError; - fn try_from(value: String) -> Result { + fn try_from(value: Base64String) -> Result { Self::new(value) } } impl Deref for Base64Type { - type Target = String; + type Target = Base64String; fn deref(&self) -> &Self::Target { &self.0 } diff --git a/xsd-parser/tests/feature/facets/mod.rs b/xsd-parser/tests/feature/facets/mod.rs index 89bdde7e..f35b6ddd 100644 --- a/xsd-parser/tests/feature/facets/mod.rs +++ b/xsd-parser/tests/feature/facets/mod.rs @@ -4,11 +4,14 @@ use xsd_parser::{ }; use crate::utils::{generate_test, ConfigEx}; +use xsd_parser_types::xml::{Base64String, HexString}; fn config() -> Config { Config::test_default() .without_optimizer_flags(OptimizerFlags::USE_UNRESTRICTED_BASE_TYPE_SIMPLE) .with_generate([(IdentType::Element, "tns:Root")]) + .with_hexbinary_type_from("::xsd_parser_types::xml::HexString") + .with_base64binary_type_from("::xsd_parser_types::xml::Base64String") } #[cfg(not(feature = "update-expectations"))] @@ -22,8 +25,8 @@ macro_rules! check_obj { assert!(matches!(it.next(), Some(RootTypeContent::NegativeDecimal(x)) if x.eq(&-1234.56_f64))); assert!(matches!(it.next(), Some(RootTypeContent::PositiveDecimal(x)) if x.eq(&0.01_f64))); assert!(matches!(it.next(), Some(RootTypeContent::RestrictedString(x)) if *x == "Abcdef")); - assert!(matches!(it.next(), Some(RootTypeContent::HexType(x)) if *x == "a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9")); - assert!(matches!(it.next(), Some(RootTypeContent::Base64Type(x)) if *x == "QUJDREVGR0hJSktMTU5PUA==")); + assert!(matches!(it.next(), Some(RootTypeContent::HexType(x)) if x.as_str() == "a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9")); + assert!(matches!(it.next(), Some(RootTypeContent::Base64Type(x)) if x.as_str() == "QUJDREVGR0hJSktMTU5PUA==")); assert!(it.next().is_none()); }}; } @@ -31,21 +34,19 @@ macro_rules! check_obj { #[cfg(not(feature = "update-expectations"))] macro_rules! test_obj { ($module:ident) => {{ - use $module::{RootType, RootTypeContent}; + use $module::{Base64Type, HexType, RootType, RootTypeContent}; RootType { content: vec![ RootTypeContent::NegativeDecimal((-1234.56_f64).try_into().unwrap()), RootTypeContent::PositiveDecimal(0.011_f64.try_into().unwrap()), RootTypeContent::RestrictedString(String::from("Abcdef").try_into().unwrap()), - RootTypeContent::HexType( - String::from("a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9") - .try_into() - .unwrap(), - ), - RootTypeContent::Base64Type( - String::from("QUJDREVGR0hJSktMTU5PUA==").try_into().unwrap(), - ), + RootTypeContent::HexType(HexType(HexString(String::from( + "a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9", + )))), + RootTypeContent::Base64Type(Base64Type(Base64String(String::from( + "QUJDREVGR0hJSktMTU5PUA==", + )))), ], } }}; From c7b5f22537544965a603c10738c2bbaa4b8370dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Oliveira?= Date: Fri, 10 Apr 2026 21:59:33 +0100 Subject: [PATCH 3/7] Implement HexBinary and Base64Binary correctly and add new test --- Cargo.lock | 90 +- Cargo.toml | 1 + xsd-parser-types/Cargo.toml | 21 +- xsd-parser-types/src/xml/base64binary.rs | 50 +- xsd-parser-types/src/xml/hexbinary.rs | 44 +- xsd-parser/Cargo.toml | 1 + .../feature/facets_binary/example/default.xml | 7 + .../feature/facets_binary/expected/default.rs | 230 +++ .../facets_binary/expected/quick_xml.rs | 1239 +++++++++++++++++ .../facets_binary/expected/serde_quick_xml.rs | 237 ++++ .../facets_binary/expected/serde_xml_rs.rs | 237 ++++ xsd-parser/tests/feature/facets_binary/mod.rs | 157 +++ .../tests/feature/facets_binary/schema.xsd | 55 + xsd-parser/tests/feature/mod.rs | 1 + 14 files changed, 2359 insertions(+), 11 deletions(-) create mode 100644 xsd-parser/tests/feature/facets_binary/example/default.xml create mode 100644 xsd-parser/tests/feature/facets_binary/expected/default.rs create mode 100644 xsd-parser/tests/feature/facets_binary/expected/quick_xml.rs create mode 100644 xsd-parser/tests/feature/facets_binary/expected/serde_quick_xml.rs create mode 100644 xsd-parser/tests/feature/facets_binary/expected/serde_xml_rs.rs create mode 100644 xsd-parser/tests/feature/facets_binary/mod.rs create mode 100644 xsd-parser/tests/feature/facets_binary/schema.xsd diff --git a/Cargo.lock b/Cargo.lock index 0ea2e915..22f1b4ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -343,6 +343,18 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "const-hex" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531185e432bb31db1ecda541e9e7ab21468d4d844ad7505e0546a49b4945d49b" +dependencies = [ + "cfg-if", + "cpufeatures", + "proptest", + "serde_core", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -359,6 +371,15 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crossterm" version = "0.29.0" @@ -1296,6 +1317,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +dependencies = [ + "bitflags", + "num-traits", + "rand 0.9.4", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "unarray", +] + [[package]] name = "ptr_meta" version = "0.1.4" @@ -1356,8 +1392,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", ] [[package]] @@ -1367,7 +1413,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", ] [[package]] @@ -1379,6 +1435,24 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + [[package]] name = "read_write" version = "0.1.0" @@ -1530,7 +1604,7 @@ dependencies = [ "borsh", "bytes", "num-traits", - "rand", + "rand 0.8.5", "rkyv", "serde", "serde_json", @@ -2190,6 +2264,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-ident" version = "1.0.18" @@ -2759,6 +2839,7 @@ dependencies = [ "bit-set", "bitflags", "clap", + "const-hex", "indexmap", "num", "parking_lot", @@ -2787,6 +2868,7 @@ name = "xsd-parser-types" version = "0.2.1" dependencies = [ "base64", + "const-hex", "encoding_rs", "futures", "indexmap", diff --git a/Cargo.toml b/Cargo.toml index 9d84cb1a..71c1d540 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ homepage = "https://github.com/Bergmann89/xsd-parser" [workspace.dependencies] anyhow = "1.0" base64 = "0.22" +const-hex = "1.17.0" bit-set = "0.8" bitflags = "2.7" bytesize = "2.3" diff --git a/xsd-parser-types/Cargo.toml b/xsd-parser-types/Cargo.toml index e7cdb2df..2439fcdf 100644 --- a/xsd-parser-types/Cargo.toml +++ b/xsd-parser-types/Cargo.toml @@ -14,23 +14,34 @@ repository.workspace = true all-features = true [features] -default = [ ] +default = [] # Enable support for async `quick-xml` de-/serialization -async = [ "dep:futures", "dep:tokio", "quick-xml/async-tokio" ] +async = ["dep:futures", "dep:tokio", "quick-xml/async-tokio"] + +# Enable support for base64 encoding/decoding +base64 = ["dep:base64"] # Enable support for dynamic xml types -xml = [ "dep:indexmap", "dep:encoding_rs" ] +xml = ["dep:indexmap", "dep:encoding_rs"] # Enable support for `quick-xml` de-/serialization -quick-xml = [ "xml", "dep:quick-xml", "dep:regex", "dep:thiserror" ] +quick-xml = [ + "xml", + "dep:quick-xml", + "dep:regex", + "dep:thiserror", + "dep:const-hex", + "dep:base64", +] [dependencies] base64 = { workspace = true, optional = true } +const-hex = { workspace = true, optional = true } encoding_rs = { workspace = true, optional = true } futures = { workspace = true, optional = true } indexmap = { workspace = true, optional = true } num = { workspace = true, optional = true } -quick-xml = { workspace = true, optional = true, features = [ "encoding" ] } +quick-xml = { workspace = true, optional = true, features = ["encoding"] } regex = { workspace = true, optional = true } serde = { workspace = true, optional = true } thiserror = { workspace = true, optional = true } diff --git a/xsd-parser-types/src/xml/base64binary.rs b/xsd-parser-types/src/xml/base64binary.rs index 12a0183d..096baeac 100644 --- a/xsd-parser-types/src/xml/base64binary.rs +++ b/xsd-parser-types/src/xml/base64binary.rs @@ -6,6 +6,9 @@ use crate::quick_xml::{ DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, }; +#[cfg(any(feature = "quick-xml", feature = "serde"))] +use base64::{engine::general_purpose, Engine as _}; + /// Wrapper for base64Binary encoded as a String. #[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -69,7 +72,6 @@ impl DeserializeBytes for Base64String { /// Wrapper for base64Binary as decoded bytes. #[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Base64Binary(pub Vec); impl Deref for Base64Binary { @@ -79,3 +81,49 @@ impl Deref for Base64Binary { &self.0 } } + +#[cfg(feature = "quick-xml")] +impl SerializeBytes for Base64Binary { + fn serialize_bytes( + &self, + _helper: &mut SerializeHelper, + ) -> Result>, Error> { + let base64_string = general_purpose::STANDARD.encode(&self.0); + Ok(Some(Cow::Owned(base64_string))) + } +} + +#[cfg(feature = "quick-xml")] +impl DeserializeBytes for Base64Binary { + fn deserialize_bytes(_helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let inner = general_purpose::STANDARD + .decode(bytes) + .map_err(Error::custom)?; + Ok(Self(inner)) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for Base64Binary { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let base64_string = general_purpose::STANDARD.encode(&self.0); + serializer.serialize_str(&base64_string) + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for Base64Binary { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let base64_string = String::deserialize(deserializer)?; + let bytes = general_purpose::STANDARD + .decode(base64_string.as_bytes()) + .map_err(|e| serde::de::Error::custom(format!("Invalid base64 string: {}", e)))?; + Ok(Self(bytes)) + } +} diff --git a/xsd-parser-types/src/xml/hexbinary.rs b/xsd-parser-types/src/xml/hexbinary.rs index 131ee655..7df62f63 100644 --- a/xsd-parser-types/src/xml/hexbinary.rs +++ b/xsd-parser-types/src/xml/hexbinary.rs @@ -68,7 +68,6 @@ impl DeserializeBytes for HexString { /// Wrapper for hexBinary as decoded bytes. #[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct HexBinary(pub Vec); impl Deref for HexBinary { @@ -78,3 +77,46 @@ impl Deref for HexBinary { &self.0 } } + +#[cfg(feature = "quick-xml")] +impl SerializeBytes for HexBinary { + fn serialize_bytes( + &self, + _helper: &mut SerializeHelper, + ) -> Result>, Error> { + let hex_string = const_hex::encode(&self.0); + Ok(Some(Cow::Owned(hex_string))) + } +} + +#[cfg(feature = "quick-xml")] +impl DeserializeBytes for HexBinary { + fn deserialize_bytes(_helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let inner = const_hex::decode(bytes).map_err(Error::custom)?; + Ok(Self(inner)) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for HexBinary { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let hex_string = const_hex::encode(&self.0); + serializer.serialize_str(&hex_string) + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for HexBinary { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let hex_string = String::deserialize(deserializer)?; + let bytes = const_hex::decode(hex_string.as_bytes()) + .map_err(|e| serde::de::Error::custom(format!("Invalid hex string: {}", e)))?; + Ok(Self(bytes)) + } +} diff --git a/xsd-parser/Cargo.toml b/xsd-parser/Cargo.toml index 49eced98..ba3e935c 100644 --- a/xsd-parser/Cargo.toml +++ b/xsd-parser/Cargo.toml @@ -44,6 +44,7 @@ xsd-parser-types = { workspace = true, features = [ "quick-xml" ] } [dev-dependencies] clap = { workspace = true, features = [ "derive" ] } +const-hex = { workspace = true } num = { workspace = true, features = [ "serde" ] } quick-xml = { workspace = true, features = [ "serialize" ]} regex = { workspace = true } diff --git a/xsd-parser/tests/feature/facets_binary/example/default.xml b/xsd-parser/tests/feature/facets_binary/example/default.xml new file mode 100644 index 00000000..455e2a56 --- /dev/null +++ b/xsd-parser/tests/feature/facets_binary/example/default.xml @@ -0,0 +1,7 @@ + + -1234.56 + 0.01 + Abcdef + a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9 + QUJDREVGR0hJSktMTU5PUA== + \ No newline at end of file diff --git a/xsd-parser/tests/feature/facets_binary/expected/default.rs b/xsd-parser/tests/feature/facets_binary/expected/default.rs new file mode 100644 index 00000000..e5e8d507 --- /dev/null +++ b/xsd-parser/tests/feature/facets_binary/expected/default.rs @@ -0,0 +1,230 @@ +use core::ops::Deref; +use regex::Regex; +use std::sync::LazyLock; +use xsd_parser_types::{ + quick_xml::{fraction_digits, ValidateError}, + xml::{Base64BinaryBytes, HexBinary}, +}; +pub type Root = RootType; +#[derive(Debug)] +pub struct RootType { + pub content: Vec, +} +#[derive(Debug)] +pub enum RootTypeContent { + NegativeDecimal(NegativeDecimalType), + PositiveDecimal(PositiveDecimalType), + RestrictedString(RestrictedStringType), + HexType(HexType), + Base64Type(Base64Type), +} +#[derive(Debug)] +pub struct NegativeDecimalType(pub f64); +impl NegativeDecimalType { + pub fn new(inner: f64) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> f64 { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + fraction_digits(s, 2usize)?; + Ok(()) + } + pub fn validate_value(value: &f64) -> Result<(), ValidateError> { + if *value < -999999999.99f64 { + return Err(ValidateError::LessThan("-999999999.99")); + } + if *value >= 0f64 { + return Err(ValidateError::GraterEqualThan("0")); + } + Ok(()) + } +} +impl From for f64 { + fn from(value: NegativeDecimalType) -> f64 { + value.0 + } +} +impl TryFrom for NegativeDecimalType { + type Error = ValidateError; + fn try_from(value: f64) -> Result { + Self::new(value) + } +} +impl Deref for NegativeDecimalType { + type Target = f64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug)] +pub struct PositiveDecimalType(pub f64); +impl PositiveDecimalType { + pub fn new(inner: f64) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> f64 { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + fraction_digits(s, 2usize)?; + Ok(()) + } + pub fn validate_value(value: &f64) -> Result<(), ValidateError> { + if *value <= 0f64 { + return Err(ValidateError::LessEqualThan("0")); + } + if *value > 999999999.99f64 { + return Err(ValidateError::GraterThan("999999999.99")); + } + Ok(()) + } +} +impl From for f64 { + fn from(value: PositiveDecimalType) -> f64 { + value.0 + } +} +impl TryFrom for PositiveDecimalType { + type Error = ValidateError; + fn try_from(value: f64) -> Result { + Self::new(value) + } +} +impl Deref for PositiveDecimalType { + type Target = f64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug)] +pub struct RestrictedStringType(pub String); +impl RestrictedStringType { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + static PATTERNS: LazyLock<[(&str, Regex); 1usize]> = LazyLock::new(|| { + [( + "[A-Z][a-z]{4,9}", + Regex::new("^(?:[A-Z][a-z]{4,9})$").unwrap(), + )] + }); + if !PATTERNS.iter().any(|(_, regex)| regex.is_match(s)) { + return Err(ValidateError::Pattern(PATTERNS[0usize].0)); + } + Ok(()) + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + if value.len() < 5usize { + return Err(ValidateError::MinLength(5usize)); + } + if value.len() > 10usize { + return Err(ValidateError::MaxLength(10usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: RestrictedStringType) -> String { + value.0 + } +} +impl TryFrom for RestrictedStringType { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for RestrictedStringType { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug)] +pub struct HexType(pub HexBinary); +impl HexType { + pub fn new(inner: HexBinary) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> HexBinary { + self.0 + } + pub fn validate_value(value: &HexBinary) -> Result<(), ValidateError> { + if value.len() < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if value.len() > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for HexBinary { + fn from(value: HexType) -> HexBinary { + value.0 + } +} +impl TryFrom for HexType { + type Error = ValidateError; + fn try_from(value: HexBinary) -> Result { + Self::new(value) + } +} +impl Deref for HexType { + type Target = HexBinary; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug)] +pub struct Base64Type(pub Base64BinaryBytes); +impl Base64Type { + pub fn new(inner: Base64BinaryBytes) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> Base64BinaryBytes { + self.0 + } + pub fn validate_value(value: &Base64BinaryBytes) -> Result<(), ValidateError> { + if value.len() < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if value.len() > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for Base64BinaryBytes { + fn from(value: Base64Type) -> Base64BinaryBytes { + value.0 + } +} +impl TryFrom for Base64Type { + type Error = ValidateError; + fn try_from(value: Base64BinaryBytes) -> Result { + Self::new(value) + } +} +impl Deref for Base64Type { + type Target = Base64BinaryBytes; + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/xsd-parser/tests/feature/facets_binary/expected/quick_xml.rs b/xsd-parser/tests/feature/facets_binary/expected/quick_xml.rs new file mode 100644 index 00000000..81290fe9 --- /dev/null +++ b/xsd-parser/tests/feature/facets_binary/expected/quick_xml.rs @@ -0,0 +1,1239 @@ +use core::{ops::Deref, str::from_utf8}; +use regex::Regex; +use std::{borrow::Cow, sync::LazyLock}; +use xsd_parser_types::{ + misc::{Namespace, NamespacePrefix}, + quick_xml::{ + fraction_digits, whitespace_collapse, DeserializeBytes, DeserializeHelper, Error, + SerializeBytes, SerializeHelper, ValidateError, WithDeserializer, + WithDeserializerFromBytes, WithSerializeToBytes, WithSerializer, + }, + xml::{Base64BinaryBytes, HexBinary}, +}; +pub const NS_XS: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema"); +pub const NS_XML: Namespace = Namespace::new_const(b"http://www.w3.org/XML/1998/namespace"); +pub const NS_XSI: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema-instance"); +pub const NS_TNS: Namespace = Namespace::new_const(b"http://example.com"); +pub const PREFIX_XS: NamespacePrefix = NamespacePrefix::new_const(b"xs"); +pub const PREFIX_XML: NamespacePrefix = NamespacePrefix::new_const(b"xml"); +pub const PREFIX_XSI: NamespacePrefix = NamespacePrefix::new_const(b"xsi"); +pub const PREFIX_TNS: NamespacePrefix = NamespacePrefix::new_const(b"tns"); +pub type Root = RootType; +#[derive(Debug)] +pub struct RootType { + pub content: Vec, +} +#[derive(Debug)] +pub enum RootTypeContent { + NegativeDecimal(NegativeDecimalType), + PositiveDecimal(PositiveDecimalType), + RestrictedString(RestrictedStringType), + HexType(HexType), + Base64Type(Base64Type), +} +impl WithSerializer for RootType { + type Serializer<'x> = quick_xml_serialize::RootTypeSerializer<'x>; + fn serializer<'ser>( + &'ser self, + name: Option<&'ser str>, + is_root: bool, + ) -> Result, Error> { + Ok(quick_xml_serialize::RootTypeSerializer { + value: self, + state: Box::new(quick_xml_serialize::RootTypeSerializerState::Init__), + name: name.unwrap_or("Root"), + is_root, + }) + } +} +impl WithSerializer for RootTypeContent { + type Serializer<'x> = quick_xml_serialize::RootTypeContentSerializer<'x>; + fn serializer<'ser>( + &'ser self, + name: Option<&'ser str>, + is_root: bool, + ) -> Result, Error> { + let _name = name; + let _is_root = is_root; + Ok(quick_xml_serialize::RootTypeContentSerializer { + value: self, + state: Box::new(quick_xml_serialize::RootTypeContentSerializerState::Init__), + }) + } +} +impl WithDeserializer for RootType { + type Deserializer = quick_xml_deserialize::RootTypeDeserializer; +} +impl WithDeserializer for RootTypeContent { + type Deserializer = quick_xml_deserialize::RootTypeContentDeserializer; +} +#[derive(Debug)] +pub struct NegativeDecimalType(pub f64); +impl NegativeDecimalType { + pub fn new(inner: f64) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> f64 { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + fraction_digits(s, 2usize)?; + Ok(()) + } + pub fn validate_value(value: &f64) -> Result<(), ValidateError> { + if *value < -999999999.99f64 { + return Err(ValidateError::LessThan("-999999999.99")); + } + if *value >= 0f64 { + return Err(ValidateError::GraterEqualThan("0")); + } + Ok(()) + } +} +impl From for f64 { + fn from(value: NegativeDecimalType) -> f64 { + value.0 + } +} +impl TryFrom for NegativeDecimalType { + type Error = ValidateError; + fn try_from(value: f64) -> Result { + Self::new(value) + } +} +impl Deref for NegativeDecimalType { + type Target = f64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl SerializeBytes for NegativeDecimalType { + fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { + let Self(inner) = self; + Ok(Some(Cow::Owned(format!("{inner:.02}")))) + } +} +impl WithSerializeToBytes for NegativeDecimalType {} +impl DeserializeBytes for NegativeDecimalType { + fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let s = from_utf8(bytes).map_err(Error::from)?; + Self::validate_str(s).map_err(|error| (bytes, error))?; + let inner = f64::deserialize_str(helper, s)?; + Ok(Self::new(inner).map_err(|error| (bytes, error))?) + } +} +impl WithDeserializerFromBytes for NegativeDecimalType {} +#[derive(Debug)] +pub struct PositiveDecimalType(pub f64); +impl PositiveDecimalType { + pub fn new(inner: f64) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> f64 { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + fraction_digits(s, 2usize)?; + Ok(()) + } + pub fn validate_value(value: &f64) -> Result<(), ValidateError> { + if *value <= 0f64 { + return Err(ValidateError::LessEqualThan("0")); + } + if *value > 999999999.99f64 { + return Err(ValidateError::GraterThan("999999999.99")); + } + Ok(()) + } +} +impl From for f64 { + fn from(value: PositiveDecimalType) -> f64 { + value.0 + } +} +impl TryFrom for PositiveDecimalType { + type Error = ValidateError; + fn try_from(value: f64) -> Result { + Self::new(value) + } +} +impl Deref for PositiveDecimalType { + type Target = f64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl SerializeBytes for PositiveDecimalType { + fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { + let Self(inner) = self; + Ok(Some(Cow::Owned(format!("{inner:.02}")))) + } +} +impl WithSerializeToBytes for PositiveDecimalType {} +impl DeserializeBytes for PositiveDecimalType { + fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let s = from_utf8(bytes).map_err(Error::from)?; + Self::validate_str(s).map_err(|error| (bytes, error))?; + let inner = f64::deserialize_str(helper, s)?; + Ok(Self::new(inner).map_err(|error| (bytes, error))?) + } +} +impl WithDeserializerFromBytes for PositiveDecimalType {} +#[derive(Debug)] +pub struct RestrictedStringType(pub String); +impl RestrictedStringType { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + static PATTERNS: LazyLock<[(&str, Regex); 1usize]> = LazyLock::new(|| { + [( + "[A-Z][a-z]{4,9}", + Regex::new("^(?:[A-Z][a-z]{4,9})$").unwrap(), + )] + }); + if !PATTERNS.iter().any(|(_, regex)| regex.is_match(s)) { + return Err(ValidateError::Pattern(PATTERNS[0usize].0)); + } + Ok(()) + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + if value.len() < 5usize { + return Err(ValidateError::MinLength(5usize)); + } + if value.len() > 10usize { + return Err(ValidateError::MaxLength(10usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: RestrictedStringType) -> String { + value.0 + } +} +impl TryFrom for RestrictedStringType { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for RestrictedStringType { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl SerializeBytes for RestrictedStringType { + fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { + self.0.serialize_bytes(helper) + } +} +impl WithSerializeToBytes for RestrictedStringType {} +impl DeserializeBytes for RestrictedStringType { + fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let s = from_utf8(bytes).map_err(Error::from)?; + let buffer = whitespace_collapse(s); + let s = buffer.trim(); + Self::validate_str(s).map_err(|error| (bytes, error))?; + let inner = String::deserialize_str(helper, s)?; + Ok(Self::new(inner).map_err(|error| (bytes, error))?) + } +} +impl WithDeserializerFromBytes for RestrictedStringType {} +#[derive(Debug)] +pub struct HexType(pub HexBinary); +impl HexType { + pub fn new(inner: HexBinary) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> HexBinary { + self.0 + } + pub fn validate_value(value: &HexBinary) -> Result<(), ValidateError> { + if value.len() < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if value.len() > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for HexBinary { + fn from(value: HexType) -> HexBinary { + value.0 + } +} +impl TryFrom for HexType { + type Error = ValidateError; + fn try_from(value: HexBinary) -> Result { + Self::new(value) + } +} +impl Deref for HexType { + type Target = HexBinary; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl SerializeBytes for HexType { + fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { + self.0.serialize_bytes(helper) + } +} +impl WithSerializeToBytes for HexType {} +impl DeserializeBytes for HexType { + fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let inner = HexBinary::deserialize_bytes(helper, bytes)?; + Ok(Self::new(inner).map_err(|error| (bytes, error))?) + } +} +impl WithDeserializerFromBytes for HexType {} +#[derive(Debug)] +pub struct Base64Type(pub Base64BinaryBytes); +impl Base64Type { + pub fn new(inner: Base64BinaryBytes) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> Base64BinaryBytes { + self.0 + } + pub fn validate_value(value: &Base64BinaryBytes) -> Result<(), ValidateError> { + if value.len() < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if value.len() > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for Base64BinaryBytes { + fn from(value: Base64Type) -> Base64BinaryBytes { + value.0 + } +} +impl TryFrom for Base64Type { + type Error = ValidateError; + fn try_from(value: Base64BinaryBytes) -> Result { + Self::new(value) + } +} +impl Deref for Base64Type { + type Target = Base64BinaryBytes; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl SerializeBytes for Base64Type { + fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { + self.0.serialize_bytes(helper) + } +} +impl WithSerializeToBytes for Base64Type {} +impl DeserializeBytes for Base64Type { + fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { + let inner = Base64BinaryBytes::deserialize_bytes(helper, bytes)?; + Ok(Self::new(inner).map_err(|error| (bytes, error))?) + } +} +impl WithDeserializerFromBytes for Base64Type {} +pub mod quick_xml_deserialize { + use core::mem::replace; + use xsd_parser_types::quick_xml::{ + BytesStart, DeserializeHelper, Deserializer, DeserializerArtifact, DeserializerEvent, + DeserializerOutput, DeserializerResult, ElementHandlerOutput, Error, ErrorKind, Event, + RawByteStr, WithDeserializer, + }; + #[derive(Debug)] + pub struct RootTypeDeserializer { + content: Vec, + state__: Box, + } + #[derive(Debug)] + enum RootTypeDeserializerState { + Init__, + Next__, + Content__(::Deserializer), + Unknown__, + } + impl RootTypeDeserializer { + fn from_bytes_start( + helper: &mut DeserializeHelper, + bytes_start: &BytesStart<'_>, + ) -> Result { + for attrib in helper.filter_xmlns_attributes(bytes_start) { + let attrib = attrib?; + helper.raise_unexpected_attrib_checked(&attrib)?; + } + Ok(Self { + content: Vec::new(), + state__: Box::new(RootTypeDeserializerState::Init__), + }) + } + fn finish_state( + &mut self, + helper: &mut DeserializeHelper, + state: RootTypeDeserializerState, + ) -> Result<(), Error> { + if let RootTypeDeserializerState::Content__(deserializer) = state { + self.store_content(deserializer.finish(helper)?)?; + } + Ok(()) + } + fn store_content(&mut self, value: super::RootTypeContent) -> Result<(), Error> { + self.content.push(value); + Ok(()) + } + fn handle_content<'de>( + &mut self, + helper: &mut DeserializeHelper, + output: DeserializerOutput<'de, super::RootTypeContent>, + fallback: &mut Option, + ) -> Result, Error> { + use RootTypeDeserializerState as S; + let DeserializerOutput { + artifact, + event, + allow_any, + } = output; + if artifact.is_none() { + *self.state__ = fallback.take().unwrap_or(S::Next__); + return Ok(ElementHandlerOutput::from_event_end(event, allow_any)); + } + if let Some(fallback) = fallback.take() { + self.finish_state(helper, fallback)?; + } + match artifact { + DeserializerArtifact::None => unreachable!(), + DeserializerArtifact::Data(data) => { + self.store_content(data)?; + *self.state__ = S::Next__; + Ok(ElementHandlerOutput::from_event(event, allow_any)) + } + DeserializerArtifact::Deserializer(deserializer) => { + *fallback = Some(S::Content__(deserializer)); + *self.state__ = S::Next__; + Ok(ElementHandlerOutput::from_event(event, allow_any)) + } + } + } + } + impl<'de> Deserializer<'de, super::RootType> for RootTypeDeserializer { + fn init( + helper: &mut DeserializeHelper, + event: Event<'de>, + ) -> DeserializerResult<'de, super::RootType> { + helper.init_deserializer_from_start_event(event, Self::from_bytes_start) + } + fn next( + mut self, + helper: &mut DeserializeHelper, + event: Event<'de>, + ) -> DeserializerResult<'de, super::RootType> { + use RootTypeDeserializerState as S; + let mut event = event; + let mut fallback = None; + let (event, allow_any) = loop { + let state = replace(&mut *self.state__, S::Unknown__); + event = match (state, event) { + (S::Unknown__, _) => unreachable!(), + (S::Content__(deserializer), event) => { + let output = deserializer.next(helper, event)?; + match self.handle_content(helper, output, &mut fallback)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + (_, Event::End(_)) => { + return Ok(DeserializerOutput { + artifact: DeserializerArtifact::Data(self.finish(helper)?), + event: DeserializerEvent::None, + allow_any: false, + }); + } + (state @ (S::Init__ | S::Next__), event) => { + fallback.get_or_insert(state); + let output = + ::init(helper, event)?; + match self.handle_content(helper, output, &mut fallback)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + } + }; + if let Some(fallback) = fallback { + *self.state__ = fallback; + } + let artifact = DeserializerArtifact::Deserializer(self); + Ok(DeserializerOutput { + artifact, + event, + allow_any, + }) + } + fn finish(mut self, helper: &mut DeserializeHelper) -> Result { + let state = replace(&mut *self.state__, RootTypeDeserializerState::Unknown__); + self.finish_state(helper, state)?; + Ok(super::RootType { + content: helper.finish_vec(0usize, None, self.content)?, + }) + } + } + #[derive(Debug)] + pub struct RootTypeContentDeserializer { + state__: Box, + } + #[derive(Debug)] + pub enum RootTypeContentDeserializerState { + Init__, + NegativeDecimal( + Option, + Option<::Deserializer>, + Option<::Deserializer>, + ), + PositiveDecimal( + Option, + Option<::Deserializer>, + Option<::Deserializer>, + ), + RestrictedString( + Option, + Option<::Deserializer>, + Option<::Deserializer>, + ), + HexType( + Option, + Option<::Deserializer>, + Option<::Deserializer>, + ), + Base64Type( + Option, + Option<::Deserializer>, + Option<::Deserializer>, + ), + Done__(super::RootTypeContent), + Unknown__, + } + impl RootTypeContentDeserializer { + fn find_suitable<'de>( + &mut self, + helper: &mut DeserializeHelper, + event: Event<'de>, + ) -> Result, Error> { + if let Event::Start(x) | Event::Empty(x) = &event { + if matches!( + helper.resolve_local_name(x.name(), &super::NS_TNS), + Some(b"NegativeDecimal") + ) { + let output = + ::init(helper, event)?; + return self.handle_negative_decimal(helper, Default::default(), None, output); + } + if matches!( + helper.resolve_local_name(x.name(), &super::NS_TNS), + Some(b"PositiveDecimal") + ) { + let output = + ::init(helper, event)?; + return self.handle_positive_decimal(helper, Default::default(), None, output); + } + if matches!( + helper.resolve_local_name(x.name(), &super::NS_TNS), + Some(b"RestrictedString") + ) { + let output = + ::init(helper, event)?; + return self.handle_restricted_string(helper, Default::default(), None, output); + } + if matches!( + helper.resolve_local_name(x.name(), &super::NS_TNS), + Some(b"HexType") + ) { + let output = ::init(helper, event)?; + return self.handle_hex_type(helper, Default::default(), None, output); + } + if matches!( + helper.resolve_local_name(x.name(), &super::NS_TNS), + Some(b"Base64Type") + ) { + let output = ::init(helper, event)?; + return self.handle_base_64_type(helper, Default::default(), None, output); + } + } + *self.state__ = RootTypeContentDeserializerState::Init__; + Ok(ElementHandlerOutput::return_to_parent(event, false)) + } + fn finish_state( + helper: &mut DeserializeHelper, + state: RootTypeContentDeserializerState, + ) -> Result { + use RootTypeContentDeserializerState as S; + match state { + S::Init__ => Err(ErrorKind::MissingContent.into()), + S::NegativeDecimal(mut values, None, deserializer) => { + if let Some(deserializer) = deserializer { + let value = deserializer.finish(helper)?; + Self::store_negative_decimal(&mut values, value)?; + } + Ok(super::RootTypeContent::NegativeDecimal( + helper.finish_element("NegativeDecimal", values)?, + )) + } + S::PositiveDecimal(mut values, None, deserializer) => { + if let Some(deserializer) = deserializer { + let value = deserializer.finish(helper)?; + Self::store_positive_decimal(&mut values, value)?; + } + Ok(super::RootTypeContent::PositiveDecimal( + helper.finish_element("PositiveDecimal", values)?, + )) + } + S::RestrictedString(mut values, None, deserializer) => { + if let Some(deserializer) = deserializer { + let value = deserializer.finish(helper)?; + Self::store_restricted_string(&mut values, value)?; + } + Ok(super::RootTypeContent::RestrictedString( + helper.finish_element("RestrictedString", values)?, + )) + } + S::HexType(mut values, None, deserializer) => { + if let Some(deserializer) = deserializer { + let value = deserializer.finish(helper)?; + Self::store_hex_type(&mut values, value)?; + } + Ok(super::RootTypeContent::HexType( + helper.finish_element("HexType", values)?, + )) + } + S::Base64Type(mut values, None, deserializer) => { + if let Some(deserializer) = deserializer { + let value = deserializer.finish(helper)?; + Self::store_base_64_type(&mut values, value)?; + } + Ok(super::RootTypeContent::Base64Type( + helper.finish_element("Base64Type", values)?, + )) + } + S::Done__(data) => Ok(data), + _ => unreachable!(), + } + } + fn store_negative_decimal( + values: &mut Option, + value: super::NegativeDecimalType, + ) -> Result<(), Error> { + if values.is_some() { + Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( + b"NegativeDecimal", + )))?; + } + *values = Some(value); + Ok(()) + } + fn store_positive_decimal( + values: &mut Option, + value: super::PositiveDecimalType, + ) -> Result<(), Error> { + if values.is_some() { + Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( + b"PositiveDecimal", + )))?; + } + *values = Some(value); + Ok(()) + } + fn store_restricted_string( + values: &mut Option, + value: super::RestrictedStringType, + ) -> Result<(), Error> { + if values.is_some() { + Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( + b"RestrictedString", + )))?; + } + *values = Some(value); + Ok(()) + } + fn store_hex_type( + values: &mut Option, + value: super::HexType, + ) -> Result<(), Error> { + if values.is_some() { + Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( + b"HexType", + )))?; + } + *values = Some(value); + Ok(()) + } + fn store_base_64_type( + values: &mut Option, + value: super::Base64Type, + ) -> Result<(), Error> { + if values.is_some() { + Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( + b"Base64Type", + )))?; + } + *values = Some(value); + Ok(()) + } + fn handle_negative_decimal<'de>( + &mut self, + helper: &mut DeserializeHelper, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, super::NegativeDecimalType>, + ) -> Result, Error> { + use RootTypeContentDeserializerState as S; + let DeserializerOutput { + artifact, + event, + allow_any, + } = output; + if artifact.is_none() { + return Ok(ElementHandlerOutput::return_to_root(event, allow_any)); + } + if let Some(deserializer) = fallback { + let data = deserializer.finish(helper)?; + Self::store_negative_decimal(&mut values, data)?; + } + match artifact { + DeserializerArtifact::None => unreachable!(), + DeserializerArtifact::Data(data) => { + Self::store_negative_decimal(&mut values, data)?; + let data = Self::finish_state(helper, S::NegativeDecimal(values, None, None))?; + *self.state__ = S::Done__(data); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + DeserializerArtifact::Deserializer(deserializer) => { + *self.state__ = S::NegativeDecimal(values, None, Some(deserializer)); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + } + } + fn handle_positive_decimal<'de>( + &mut self, + helper: &mut DeserializeHelper, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, super::PositiveDecimalType>, + ) -> Result, Error> { + use RootTypeContentDeserializerState as S; + let DeserializerOutput { + artifact, + event, + allow_any, + } = output; + if artifact.is_none() { + return Ok(ElementHandlerOutput::return_to_root(event, allow_any)); + } + if let Some(deserializer) = fallback { + let data = deserializer.finish(helper)?; + Self::store_positive_decimal(&mut values, data)?; + } + match artifact { + DeserializerArtifact::None => unreachable!(), + DeserializerArtifact::Data(data) => { + Self::store_positive_decimal(&mut values, data)?; + let data = Self::finish_state(helper, S::PositiveDecimal(values, None, None))?; + *self.state__ = S::Done__(data); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + DeserializerArtifact::Deserializer(deserializer) => { + *self.state__ = S::PositiveDecimal(values, None, Some(deserializer)); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + } + } + fn handle_restricted_string<'de>( + &mut self, + helper: &mut DeserializeHelper, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, super::RestrictedStringType>, + ) -> Result, Error> { + use RootTypeContentDeserializerState as S; + let DeserializerOutput { + artifact, + event, + allow_any, + } = output; + if artifact.is_none() { + return Ok(ElementHandlerOutput::return_to_root(event, allow_any)); + } + if let Some(deserializer) = fallback { + let data = deserializer.finish(helper)?; + Self::store_restricted_string(&mut values, data)?; + } + match artifact { + DeserializerArtifact::None => unreachable!(), + DeserializerArtifact::Data(data) => { + Self::store_restricted_string(&mut values, data)?; + let data = Self::finish_state(helper, S::RestrictedString(values, None, None))?; + *self.state__ = S::Done__(data); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + DeserializerArtifact::Deserializer(deserializer) => { + *self.state__ = S::RestrictedString(values, None, Some(deserializer)); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + } + } + fn handle_hex_type<'de>( + &mut self, + helper: &mut DeserializeHelper, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, super::HexType>, + ) -> Result, Error> { + use RootTypeContentDeserializerState as S; + let DeserializerOutput { + artifact, + event, + allow_any, + } = output; + if artifact.is_none() { + return Ok(ElementHandlerOutput::return_to_root(event, allow_any)); + } + if let Some(deserializer) = fallback { + let data = deserializer.finish(helper)?; + Self::store_hex_type(&mut values, data)?; + } + match artifact { + DeserializerArtifact::None => unreachable!(), + DeserializerArtifact::Data(data) => { + Self::store_hex_type(&mut values, data)?; + let data = Self::finish_state(helper, S::HexType(values, None, None))?; + *self.state__ = S::Done__(data); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + DeserializerArtifact::Deserializer(deserializer) => { + *self.state__ = S::HexType(values, None, Some(deserializer)); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + } + } + fn handle_base_64_type<'de>( + &mut self, + helper: &mut DeserializeHelper, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, super::Base64Type>, + ) -> Result, Error> { + use RootTypeContentDeserializerState as S; + let DeserializerOutput { + artifact, + event, + allow_any, + } = output; + if artifact.is_none() { + return Ok(ElementHandlerOutput::return_to_root(event, allow_any)); + } + if let Some(deserializer) = fallback { + let data = deserializer.finish(helper)?; + Self::store_base_64_type(&mut values, data)?; + } + match artifact { + DeserializerArtifact::None => unreachable!(), + DeserializerArtifact::Data(data) => { + Self::store_base_64_type(&mut values, data)?; + let data = Self::finish_state(helper, S::Base64Type(values, None, None))?; + *self.state__ = S::Done__(data); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + DeserializerArtifact::Deserializer(deserializer) => { + *self.state__ = S::Base64Type(values, None, Some(deserializer)); + Ok(ElementHandlerOutput::break_(event, allow_any)) + } + } + } + } + impl<'de> Deserializer<'de, super::RootTypeContent> for RootTypeContentDeserializer { + fn init( + helper: &mut DeserializeHelper, + event: Event<'de>, + ) -> DeserializerResult<'de, super::RootTypeContent> { + let deserializer = Self { + state__: Box::new(RootTypeContentDeserializerState::Init__), + }; + let mut output = deserializer.next(helper, event)?; + output.artifact = match output.artifact { + DeserializerArtifact::Deserializer(x) + if matches!(&*x.state__, RootTypeContentDeserializerState::Init__) => + { + DeserializerArtifact::None + } + artifact => artifact, + }; + Ok(output) + } + fn next( + mut self, + helper: &mut DeserializeHelper, + event: Event<'de>, + ) -> DeserializerResult<'de, super::RootTypeContent> { + use RootTypeContentDeserializerState as S; + let mut event = event; + let (event, allow_any) = loop { + let state = replace(&mut *self.state__, S::Unknown__); + event = match (state, event) { + (S::Unknown__, _) => unreachable!(), + (S::NegativeDecimal(values, fallback, Some(deserializer)), event) => { + let output = deserializer.next(helper, event)?; + match self.handle_negative_decimal(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + (S::PositiveDecimal(values, fallback, Some(deserializer)), event) => { + let output = deserializer.next(helper, event)?; + match self.handle_positive_decimal(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + (S::RestrictedString(values, fallback, Some(deserializer)), event) => { + let output = deserializer.next(helper, event)?; + match self.handle_restricted_string(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + (S::HexType(values, fallback, Some(deserializer)), event) => { + let output = deserializer.next(helper, event)?; + match self.handle_hex_type(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + (S::Base64Type(values, fallback, Some(deserializer)), event) => { + let output = deserializer.next(helper, event)?; + match self.handle_base_64_type(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + (state, event @ Event::End(_)) => { + return Ok(DeserializerOutput { + artifact: DeserializerArtifact::Data(Self::finish_state( + helper, state, + )?), + event: DeserializerEvent::Continue(event), + allow_any: false, + }); + } + (S::Init__, event) => match self.find_suitable(helper, event)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + }, + ( + S::NegativeDecimal(values, fallback, None), + event @ (Event::Start(_) | Event::Empty(_)), + ) => { + let output = helper.init_start_tag_deserializer( + event, + Some(&super::NS_TNS), + b"NegativeDecimal", + false, + )?; + match self.handle_negative_decimal(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + ( + S::PositiveDecimal(values, fallback, None), + event @ (Event::Start(_) | Event::Empty(_)), + ) => { + let output = helper.init_start_tag_deserializer( + event, + Some(&super::NS_TNS), + b"PositiveDecimal", + false, + )?; + match self.handle_positive_decimal(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + ( + S::RestrictedString(values, fallback, None), + event @ (Event::Start(_) | Event::Empty(_)), + ) => { + let output = helper.init_start_tag_deserializer( + event, + Some(&super::NS_TNS), + b"RestrictedString", + false, + )?; + match self.handle_restricted_string(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + ( + S::HexType(values, fallback, None), + event @ (Event::Start(_) | Event::Empty(_)), + ) => { + let output = helper.init_start_tag_deserializer( + event, + Some(&super::NS_TNS), + b"HexType", + false, + )?; + match self.handle_hex_type(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + ( + S::Base64Type(values, fallback, None), + event @ (Event::Start(_) | Event::Empty(_)), + ) => { + let output = helper.init_start_tag_deserializer( + event, + Some(&super::NS_TNS), + b"Base64Type", + false, + )?; + match self.handle_base_64_type(helper, values, fallback, output)? { + ElementHandlerOutput::Break { event, allow_any } => { + break (event, allow_any) + } + ElementHandlerOutput::Continue { event, .. } => event, + } + } + (state @ S::Done__(_), event) => { + *self.state__ = state; + break (DeserializerEvent::Continue(event), false); + } + (state, event) => { + *self.state__ = state; + break (DeserializerEvent::Continue(event), false); + } + } + }; + let artifact = if matches!(&*self.state__, S::Done__(_)) { + DeserializerArtifact::Data(self.finish(helper)?) + } else { + DeserializerArtifact::Deserializer(self) + }; + Ok(DeserializerOutput { + artifact, + event, + allow_any, + }) + } + fn finish(self, helper: &mut DeserializeHelper) -> Result { + Self::finish_state(helper, *self.state__) + } + } +} +pub mod quick_xml_serialize { + use xsd_parser_types::quick_xml::{ + BytesEnd, BytesStart, Error, Event, IterSerializer, SerializeHelper, Serializer, + WithSerializer, + }; + #[derive(Debug)] + pub struct RootTypeSerializer<'ser> { + pub(super) value: &'ser super::RootType, + pub(super) state: Box>, + pub(super) name: &'ser str, + pub(super) is_root: bool, + } + #[derive(Debug)] + pub(super) enum RootTypeSerializerState<'ser> { + Init__, + Content__(IterSerializer<'ser, &'ser [super::RootTypeContent], super::RootTypeContent>), + End__, + Done__, + Phantom__(&'ser ()), + } + impl<'ser> RootTypeSerializer<'ser> { + fn next_event( + &mut self, + helper: &mut SerializeHelper, + ) -> Result>, Error> { + loop { + match &mut *self.state { + RootTypeSerializerState::Init__ => { + *self.state = RootTypeSerializerState::Content__(IterSerializer::new( + &self.value.content[..], + None, + false, + )); + let mut bytes = BytesStart::new(self.name); + helper.begin_ns_scope(); + if self.is_root { + helper.write_xmlns_for_tag(&mut bytes, self.name, &super::NS_TNS); + } + return Ok(Some(Event::Start(bytes))); + } + RootTypeSerializerState::Content__(x) => match x.next(helper).transpose()? { + Some(event) => return Ok(Some(event)), + None => *self.state = RootTypeSerializerState::End__, + }, + RootTypeSerializerState::End__ => { + *self.state = RootTypeSerializerState::Done__; + helper.end_ns_scope(); + return Ok(Some(Event::End(BytesEnd::new(self.name)))); + } + RootTypeSerializerState::Done__ => return Ok(None), + RootTypeSerializerState::Phantom__(_) => unreachable!(), + } + } + } + } + impl<'ser> Serializer<'ser> for RootTypeSerializer<'ser> { + fn next(&mut self, helper: &mut SerializeHelper) -> Option, Error>> { + match self.next_event(helper) { + Ok(Some(event)) => Some(Ok(event)), + Ok(None) => None, + Err(error) => { + *self.state = RootTypeSerializerState::Done__; + Some(Err(error)) + } + } + } + } + #[derive(Debug)] + pub struct RootTypeContentSerializer<'ser> { + pub(super) value: &'ser super::RootTypeContent, + pub(super) state: Box>, + } + #[derive(Debug)] + pub(super) enum RootTypeContentSerializerState<'ser> { + Init__, + NegativeDecimal(::Serializer<'ser>), + PositiveDecimal(::Serializer<'ser>), + RestrictedString(::Serializer<'ser>), + HexType(::Serializer<'ser>), + Base64Type(::Serializer<'ser>), + Done__, + Phantom__(&'ser ()), + } + impl<'ser> RootTypeContentSerializer<'ser> { + fn next_event( + &mut self, + helper: &mut SerializeHelper, + ) -> Result>, Error> { + loop { + match &mut *self.state { + RootTypeContentSerializerState::Init__ => match self.value { + super::RootTypeContent::NegativeDecimal(x) => { + *self.state = RootTypeContentSerializerState::NegativeDecimal( + WithSerializer::serializer(x, Some("NegativeDecimal"), false)?, + ) + } + super::RootTypeContent::PositiveDecimal(x) => { + *self.state = RootTypeContentSerializerState::PositiveDecimal( + WithSerializer::serializer(x, Some("PositiveDecimal"), false)?, + ) + } + super::RootTypeContent::RestrictedString(x) => { + *self.state = RootTypeContentSerializerState::RestrictedString( + WithSerializer::serializer(x, Some("RestrictedString"), false)?, + ) + } + super::RootTypeContent::HexType(x) => { + *self.state = RootTypeContentSerializerState::HexType( + WithSerializer::serializer(x, Some("HexType"), false)?, + ) + } + super::RootTypeContent::Base64Type(x) => { + *self.state = RootTypeContentSerializerState::Base64Type( + WithSerializer::serializer(x, Some("Base64Type"), false)?, + ) + } + }, + RootTypeContentSerializerState::NegativeDecimal(x) => { + match x.next(helper).transpose()? { + Some(event) => return Ok(Some(event)), + None => *self.state = RootTypeContentSerializerState::Done__, + } + } + RootTypeContentSerializerState::PositiveDecimal(x) => { + match x.next(helper).transpose()? { + Some(event) => return Ok(Some(event)), + None => *self.state = RootTypeContentSerializerState::Done__, + } + } + RootTypeContentSerializerState::RestrictedString(x) => { + match x.next(helper).transpose()? { + Some(event) => return Ok(Some(event)), + None => *self.state = RootTypeContentSerializerState::Done__, + } + } + RootTypeContentSerializerState::HexType(x) => { + match x.next(helper).transpose()? { + Some(event) => return Ok(Some(event)), + None => *self.state = RootTypeContentSerializerState::Done__, + } + } + RootTypeContentSerializerState::Base64Type(x) => { + match x.next(helper).transpose()? { + Some(event) => return Ok(Some(event)), + None => *self.state = RootTypeContentSerializerState::Done__, + } + } + RootTypeContentSerializerState::Done__ => return Ok(None), + RootTypeContentSerializerState::Phantom__(_) => unreachable!(), + } + } + } + } + impl<'ser> Serializer<'ser> for RootTypeContentSerializer<'ser> { + fn next(&mut self, helper: &mut SerializeHelper) -> Option, Error>> { + match self.next_event(helper) { + Ok(Some(event)) => Some(Ok(event)), + Ok(None) => None, + Err(error) => { + *self.state = RootTypeContentSerializerState::Done__; + Some(Err(error)) + } + } + } + } +} diff --git a/xsd-parser/tests/feature/facets_binary/expected/serde_quick_xml.rs b/xsd-parser/tests/feature/facets_binary/expected/serde_quick_xml.rs new file mode 100644 index 00000000..f51a2f5d --- /dev/null +++ b/xsd-parser/tests/feature/facets_binary/expected/serde_quick_xml.rs @@ -0,0 +1,237 @@ +use core::ops::Deref; +use regex::Regex; +use serde::{Deserialize, Serialize}; +use std::sync::LazyLock; +use xsd_parser_types::{ + quick_xml::{fraction_digits, ValidateError}, + xml::{Base64BinaryBytes, HexBinary}, +}; +pub type Root = RootType; +#[derive(Debug, Deserialize, Serialize)] +pub struct RootType { + #[serde(default, rename = "$value")] + pub content: Vec, +} +#[derive(Debug, Deserialize, Serialize)] +pub enum RootTypeContent { + #[serde(rename = "NegativeDecimal")] + NegativeDecimal(NegativeDecimalType), + #[serde(rename = "PositiveDecimal")] + PositiveDecimal(PositiveDecimalType), + #[serde(rename = "RestrictedString")] + RestrictedString(RestrictedStringType), + #[serde(rename = "HexType")] + HexType(HexType), + #[serde(rename = "Base64Type")] + Base64Type(Base64Type), +} +#[derive(Debug, Deserialize, Serialize)] +pub struct NegativeDecimalType(pub f64); +impl NegativeDecimalType { + pub fn new(inner: f64) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> f64 { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + fraction_digits(s, 2usize)?; + Ok(()) + } + pub fn validate_value(value: &f64) -> Result<(), ValidateError> { + if *value < -999999999.99f64 { + return Err(ValidateError::LessThan("-999999999.99")); + } + if *value >= 0f64 { + return Err(ValidateError::GraterEqualThan("0")); + } + Ok(()) + } +} +impl From for f64 { + fn from(value: NegativeDecimalType) -> f64 { + value.0 + } +} +impl TryFrom for NegativeDecimalType { + type Error = ValidateError; + fn try_from(value: f64) -> Result { + Self::new(value) + } +} +impl Deref for NegativeDecimalType { + type Target = f64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct PositiveDecimalType(pub f64); +impl PositiveDecimalType { + pub fn new(inner: f64) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> f64 { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + fraction_digits(s, 2usize)?; + Ok(()) + } + pub fn validate_value(value: &f64) -> Result<(), ValidateError> { + if *value <= 0f64 { + return Err(ValidateError::LessEqualThan("0")); + } + if *value > 999999999.99f64 { + return Err(ValidateError::GraterThan("999999999.99")); + } + Ok(()) + } +} +impl From for f64 { + fn from(value: PositiveDecimalType) -> f64 { + value.0 + } +} +impl TryFrom for PositiveDecimalType { + type Error = ValidateError; + fn try_from(value: f64) -> Result { + Self::new(value) + } +} +impl Deref for PositiveDecimalType { + type Target = f64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct RestrictedStringType(pub String); +impl RestrictedStringType { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + static PATTERNS: LazyLock<[(&str, Regex); 1usize]> = LazyLock::new(|| { + [( + "[A-Z][a-z]{4,9}", + Regex::new("^(?:[A-Z][a-z]{4,9})$").unwrap(), + )] + }); + if !PATTERNS.iter().any(|(_, regex)| regex.is_match(s)) { + return Err(ValidateError::Pattern(PATTERNS[0usize].0)); + } + Ok(()) + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + if value.len() < 5usize { + return Err(ValidateError::MinLength(5usize)); + } + if value.len() > 10usize { + return Err(ValidateError::MaxLength(10usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: RestrictedStringType) -> String { + value.0 + } +} +impl TryFrom for RestrictedStringType { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for RestrictedStringType { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct HexType(pub HexBinary); +impl HexType { + pub fn new(inner: HexBinary) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> HexBinary { + self.0 + } + pub fn validate_value(value: &HexBinary) -> Result<(), ValidateError> { + if value.len() < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if value.len() > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for HexBinary { + fn from(value: HexType) -> HexBinary { + value.0 + } +} +impl TryFrom for HexType { + type Error = ValidateError; + fn try_from(value: HexBinary) -> Result { + Self::new(value) + } +} +impl Deref for HexType { + type Target = HexBinary; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct Base64Type(pub Base64BinaryBytes); +impl Base64Type { + pub fn new(inner: Base64BinaryBytes) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> Base64BinaryBytes { + self.0 + } + pub fn validate_value(value: &Base64BinaryBytes) -> Result<(), ValidateError> { + if value.len() < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if value.len() > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for Base64BinaryBytes { + fn from(value: Base64Type) -> Base64BinaryBytes { + value.0 + } +} +impl TryFrom for Base64Type { + type Error = ValidateError; + fn try_from(value: Base64BinaryBytes) -> Result { + Self::new(value) + } +} +impl Deref for Base64Type { + type Target = Base64BinaryBytes; + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/xsd-parser/tests/feature/facets_binary/expected/serde_xml_rs.rs b/xsd-parser/tests/feature/facets_binary/expected/serde_xml_rs.rs new file mode 100644 index 00000000..3dcbe9bc --- /dev/null +++ b/xsd-parser/tests/feature/facets_binary/expected/serde_xml_rs.rs @@ -0,0 +1,237 @@ +use core::ops::Deref; +use regex::Regex; +use serde::{Deserialize, Serialize}; +use std::sync::LazyLock; +use xsd_parser_types::{ + quick_xml::{fraction_digits, ValidateError}, + xml::{Base64BinaryBytes, HexBinary}, +}; +pub type Root = RootType; +#[derive(Debug, Deserialize, Serialize)] +pub struct RootType { + #[serde(default, rename = "#content")] + pub content: Vec, +} +#[derive(Debug, Deserialize, Serialize)] +pub enum RootTypeContent { + #[serde(rename = "NegativeDecimal")] + NegativeDecimal(NegativeDecimalType), + #[serde(rename = "PositiveDecimal")] + PositiveDecimal(PositiveDecimalType), + #[serde(rename = "RestrictedString")] + RestrictedString(RestrictedStringType), + #[serde(rename = "HexType")] + HexType(HexType), + #[serde(rename = "Base64Type")] + Base64Type(Base64Type), +} +#[derive(Debug, Deserialize, Serialize)] +pub struct NegativeDecimalType(pub f64); +impl NegativeDecimalType { + pub fn new(inner: f64) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> f64 { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + fraction_digits(s, 2usize)?; + Ok(()) + } + pub fn validate_value(value: &f64) -> Result<(), ValidateError> { + if *value < -999999999.99f64 { + return Err(ValidateError::LessThan("-999999999.99")); + } + if *value >= 0f64 { + return Err(ValidateError::GraterEqualThan("0")); + } + Ok(()) + } +} +impl From for f64 { + fn from(value: NegativeDecimalType) -> f64 { + value.0 + } +} +impl TryFrom for NegativeDecimalType { + type Error = ValidateError; + fn try_from(value: f64) -> Result { + Self::new(value) + } +} +impl Deref for NegativeDecimalType { + type Target = f64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct PositiveDecimalType(pub f64); +impl PositiveDecimalType { + pub fn new(inner: f64) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> f64 { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + fraction_digits(s, 2usize)?; + Ok(()) + } + pub fn validate_value(value: &f64) -> Result<(), ValidateError> { + if *value <= 0f64 { + return Err(ValidateError::LessEqualThan("0")); + } + if *value > 999999999.99f64 { + return Err(ValidateError::GraterThan("999999999.99")); + } + Ok(()) + } +} +impl From for f64 { + fn from(value: PositiveDecimalType) -> f64 { + value.0 + } +} +impl TryFrom for PositiveDecimalType { + type Error = ValidateError; + fn try_from(value: f64) -> Result { + Self::new(value) + } +} +impl Deref for PositiveDecimalType { + type Target = f64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct RestrictedStringType(pub String); +impl RestrictedStringType { + pub fn new(inner: String) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> String { + self.0 + } + pub fn validate_str(s: &str) -> Result<(), ValidateError> { + static PATTERNS: LazyLock<[(&str, Regex); 1usize]> = LazyLock::new(|| { + [( + "[A-Z][a-z]{4,9}", + Regex::new("^(?:[A-Z][a-z]{4,9})$").unwrap(), + )] + }); + if !PATTERNS.iter().any(|(_, regex)| regex.is_match(s)) { + return Err(ValidateError::Pattern(PATTERNS[0usize].0)); + } + Ok(()) + } + pub fn validate_value(value: &String) -> Result<(), ValidateError> { + if value.len() < 5usize { + return Err(ValidateError::MinLength(5usize)); + } + if value.len() > 10usize { + return Err(ValidateError::MaxLength(10usize)); + } + Ok(()) + } +} +impl From for String { + fn from(value: RestrictedStringType) -> String { + value.0 + } +} +impl TryFrom for RestrictedStringType { + type Error = ValidateError; + fn try_from(value: String) -> Result { + Self::new(value) + } +} +impl Deref for RestrictedStringType { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct HexType(pub HexBinary); +impl HexType { + pub fn new(inner: HexBinary) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> HexBinary { + self.0 + } + pub fn validate_value(value: &HexBinary) -> Result<(), ValidateError> { + if value.len() < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if value.len() > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for HexBinary { + fn from(value: HexType) -> HexBinary { + value.0 + } +} +impl TryFrom for HexType { + type Error = ValidateError; + fn try_from(value: HexBinary) -> Result { + Self::new(value) + } +} +impl Deref for HexType { + type Target = HexBinary; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +#[derive(Debug, Deserialize, Serialize)] +pub struct Base64Type(pub Base64BinaryBytes); +impl Base64Type { + pub fn new(inner: Base64BinaryBytes) -> Result { + Self::validate_value(&inner)?; + Ok(Self(inner)) + } + #[must_use] + pub fn into_inner(self) -> Base64BinaryBytes { + self.0 + } + pub fn validate_value(value: &Base64BinaryBytes) -> Result<(), ValidateError> { + if value.len() < 16usize { + return Err(ValidateError::MinLength(16usize)); + } + if value.len() > 16usize { + return Err(ValidateError::MaxLength(16usize)); + } + Ok(()) + } +} +impl From for Base64BinaryBytes { + fn from(value: Base64Type) -> Base64BinaryBytes { + value.0 + } +} +impl TryFrom for Base64Type { + type Error = ValidateError; + fn try_from(value: Base64BinaryBytes) -> Result { + Self::new(value) + } +} +impl Deref for Base64Type { + type Target = Base64BinaryBytes; + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/xsd-parser/tests/feature/facets_binary/mod.rs b/xsd-parser/tests/feature/facets_binary/mod.rs new file mode 100644 index 00000000..8713c6ef --- /dev/null +++ b/xsd-parser/tests/feature/facets_binary/mod.rs @@ -0,0 +1,157 @@ +use xsd_parser::{ + config::{OptimizerFlags, SerdeXmlRsVersion}, + Config, IdentType, +}; + +use crate::utils::{generate_test, ConfigEx}; +use xsd_parser_types::xml::{Base64BinaryBytes, HexBinary}; + +fn config() -> Config { + Config::test_default() + .without_optimizer_flags(OptimizerFlags::USE_UNRESTRICTED_BASE_TYPE_SIMPLE) + .with_generate([(IdentType::Element, "tns:Root")]) + .with_hexbinary_type() + .with_base64binary_type() +} + +#[cfg(not(feature = "update-expectations"))] +macro_rules! check_obj { + ($module:ident, $obj:expr) => {{ + use $module::RootTypeContent; + + let obj = $obj; + + let mut it = obj.content.into_iter(); + assert!(matches!(it.next(), Some(RootTypeContent::NegativeDecimal(x)) if x.eq(&-1234.56_f64))); + assert!(matches!(it.next(), Some(RootTypeContent::PositiveDecimal(x)) if x.eq(&0.01_f64))); + assert!(matches!(it.next(), Some(RootTypeContent::RestrictedString(x)) if *x == "Abcdef")); + assert!(matches!(it.next(), Some(RootTypeContent::HexType(x)) if x.0 == HexBinary(const_hex::decode("a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9").unwrap()))); + assert!(matches!(it.next(), Some(RootTypeContent::Base64Type(x)) if *x == Base64BinaryBytes( b"ABCDEFGHIJKLMNOP".to_vec()))); + assert!(it.next().is_none()); + }}; +} + +#[cfg(not(feature = "update-expectations"))] +macro_rules! test_obj { + ($module:ident) => {{ + use $module::{Base64Type, HexType, RootType, RootTypeContent}; + + RootType { + content: vec![ + RootTypeContent::NegativeDecimal((-1234.56_f64).try_into().unwrap()), + RootTypeContent::PositiveDecimal(0.011_f64.try_into().unwrap()), + RootTypeContent::RestrictedString(String::from("Abcdef").try_into().unwrap()), + RootTypeContent::HexType(HexType(HexBinary( + const_hex::decode("a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9").unwrap(), + ))), + RootTypeContent::Base64Type(Base64Type(Base64BinaryBytes( + b"ABCDEFGHIJKLMNOP".to_vec(), + ))), + ], + } + }}; +} + +/* default */ + +#[test] +fn generate_default() { + generate_test( + "tests/feature/facets_binary/schema.xsd", + "tests/feature/facets_binary/expected/default.rs", + config(), + ); +} + +#[cfg(not(feature = "update-expectations"))] +mod default { + #![allow(unused_imports)] + + include!("expected/default.rs"); +} + +/* quick_xml */ + +#[test] +fn generate_quick_xml() { + generate_test( + "tests/feature/facets_binary/schema.xsd", + "tests/feature/facets_binary/expected/quick_xml.rs", + config().with_quick_xml(), + ); +} + +#[test] +#[cfg(not(feature = "update-expectations"))] +fn read_quick_xml() { + use quick_xml::RootType; + + let obj = crate::utils::quick_xml_read_test::( + "tests/feature/facets_binary/example/default.xml", + ); + + check_obj!(quick_xml, obj); +} + +#[test] +#[cfg(not(feature = "update-expectations"))] +fn write_quick_xml() { + let obj = test_obj!(quick_xml); + + crate::utils::quick_xml_write_test(&obj, "Values", "tests/feature/facets/example/default.xml"); +} + +#[cfg(not(feature = "update-expectations"))] +mod quick_xml { + #![allow(unused_imports)] + + include!("expected/quick_xml.rs"); +} + +/* serde_xml_rs */ + +#[test] +fn generate_serde_xml_rs() { + generate_test( + "tests/feature/facets_binary/schema.xsd", + "tests/feature/facets_binary/expected/serde_xml_rs.rs", + config().with_serde_xml_rs(SerdeXmlRsVersion::Version08AndAbove), + ); +} + +#[test] +#[cfg(not(feature = "update-expectations"))] +fn read_serde_xml_rs() { + use serde_xml_rs::RootType; + + let obj = crate::utils::serde_xml_rs_read_test::( + "tests/feature/facets_binary/example/default.xml", + ); + + check_obj!(serde_xml_rs, obj); +} + +#[cfg(not(feature = "update-expectations"))] +mod serde_xml_rs { + #![allow(unused_imports)] + + include!("expected/serde_xml_rs.rs"); +} + +/* serde_quick_xml */ + +#[test] +fn generate_serde_quick_xml() { + generate_test( + "tests/feature/facets_binary/schema.xsd", + "tests/feature/facets_binary/expected/serde_quick_xml.rs", + config().with_serde_quick_xml(), + ); +} + +#[cfg(not(feature = "update-expectations"))] +mod serde_quick_xml { + #![allow(unused_imports)] + + include!("expected/serde_quick_xml.rs"); +} diff --git a/xsd-parser/tests/feature/facets_binary/schema.xsd b/xsd-parser/tests/feature/facets_binary/schema.xsd new file mode 100644 index 00000000..84d76c93 --- /dev/null +++ b/xsd-parser/tests/feature/facets_binary/schema.xsd @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xsd-parser/tests/feature/mod.rs b/xsd-parser/tests/feature/mod.rs index c9b2d29a..4bc29b39 100644 --- a/xsd-parser/tests/feature/mod.rs +++ b/xsd-parser/tests/feature/mod.rs @@ -34,6 +34,7 @@ mod extension_mixed_content; mod extension_simple_content; mod extra_derive; mod facets; +mod facets_binary; mod globally_allowed_attribute; mod group_modules; mod group_optional_followed_by_element; From bfb009cb03f84f73758d81ab7fd3fdd2203dadfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Oliveira?= Date: Thu, 16 Apr 2026 04:02:39 +0100 Subject: [PATCH 4/7] Fix include errors --- xsd-parser/tests/feature/facets/mod.rs | 9 ++++----- xsd-parser/tests/feature/facets_binary/mod.rs | 15 +++++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/xsd-parser/tests/feature/facets/mod.rs b/xsd-parser/tests/feature/facets/mod.rs index f35b6ddd..b13c0c6e 100644 --- a/xsd-parser/tests/feature/facets/mod.rs +++ b/xsd-parser/tests/feature/facets/mod.rs @@ -4,7 +4,6 @@ use xsd_parser::{ }; use crate::utils::{generate_test, ConfigEx}; -use xsd_parser_types::xml::{Base64String, HexString}; fn config() -> Config { Config::test_default() @@ -41,12 +40,12 @@ macro_rules! test_obj { RootTypeContent::NegativeDecimal((-1234.56_f64).try_into().unwrap()), RootTypeContent::PositiveDecimal(0.011_f64.try_into().unwrap()), RootTypeContent::RestrictedString(String::from("Abcdef").try_into().unwrap()), - RootTypeContent::HexType(HexType(HexString(String::from( + RootTypeContent::HexType(HexType(xsd_parser_types::xml::HexString(String::from( "a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9", )))), - RootTypeContent::Base64Type(Base64Type(Base64String(String::from( - "QUJDREVGR0hJSktMTU5PUA==", - )))), + RootTypeContent::Base64Type(Base64Type(xsd_parser_types::xml::Base64String( + String::from("QUJDREVGR0hJSktMTU5PUA=="), + ))), ], } }}; diff --git a/xsd-parser/tests/feature/facets_binary/mod.rs b/xsd-parser/tests/feature/facets_binary/mod.rs index 8713c6ef..070f5797 100644 --- a/xsd-parser/tests/feature/facets_binary/mod.rs +++ b/xsd-parser/tests/feature/facets_binary/mod.rs @@ -4,7 +4,6 @@ use xsd_parser::{ }; use crate::utils::{generate_test, ConfigEx}; -use xsd_parser_types::xml::{Base64BinaryBytes, HexBinary}; fn config() -> Config { Config::test_default() @@ -25,8 +24,8 @@ macro_rules! check_obj { assert!(matches!(it.next(), Some(RootTypeContent::NegativeDecimal(x)) if x.eq(&-1234.56_f64))); assert!(matches!(it.next(), Some(RootTypeContent::PositiveDecimal(x)) if x.eq(&0.01_f64))); assert!(matches!(it.next(), Some(RootTypeContent::RestrictedString(x)) if *x == "Abcdef")); - assert!(matches!(it.next(), Some(RootTypeContent::HexType(x)) if x.0 == HexBinary(const_hex::decode("a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9").unwrap()))); - assert!(matches!(it.next(), Some(RootTypeContent::Base64Type(x)) if *x == Base64BinaryBytes( b"ABCDEFGHIJKLMNOP".to_vec()))); + assert!(matches!(it.next(), Some(RootTypeContent::HexType(x)) if x.0 == xsd_parser_types::xml::HexBinary(const_hex::decode("a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9").unwrap()))); + assert!(matches!(it.next(), Some(RootTypeContent::Base64Type(x)) if *x == xsd_parser_types::xml::Base64BinaryBytes(b"ABCDEFGHIJKLMNOP".to_vec()))); assert!(it.next().is_none()); }}; } @@ -41,10 +40,10 @@ macro_rules! test_obj { RootTypeContent::NegativeDecimal((-1234.56_f64).try_into().unwrap()), RootTypeContent::PositiveDecimal(0.011_f64.try_into().unwrap()), RootTypeContent::RestrictedString(String::from("Abcdef").try_into().unwrap()), - RootTypeContent::HexType(HexType(HexBinary( + RootTypeContent::HexType(HexType(xsd_parser_types::xml::HexBinary( const_hex::decode("a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9").unwrap(), ))), - RootTypeContent::Base64Type(Base64Type(Base64BinaryBytes( + RootTypeContent::Base64Type(Base64Type(xsd_parser_types::xml::Base64BinaryBytes( b"ABCDEFGHIJKLMNOP".to_vec(), ))), ], @@ -98,7 +97,11 @@ fn read_quick_xml() { fn write_quick_xml() { let obj = test_obj!(quick_xml); - crate::utils::quick_xml_write_test(&obj, "Values", "tests/feature/facets/example/default.xml"); + crate::utils::quick_xml_write_test( + &obj, + "Values", + "tests/feature/facets_binary/example/default.xml", + ); } #[cfg(not(feature = "update-expectations"))] From e3b3edfe8996d782a89ca10b958f9597a98327b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Oliveira?= Date: Tue, 21 Apr 2026 14:07:10 +0100 Subject: [PATCH 5/7] Rename files as sugested --- xsd-parser-types/src/xml/{base64binary.rs => base64.rs} | 0 xsd-parser-types/src/xml/{hexbinary.rs => hex.rs} | 0 xsd-parser-types/src/xml/mod.rs | 8 ++++---- 3 files changed, 4 insertions(+), 4 deletions(-) rename xsd-parser-types/src/xml/{base64binary.rs => base64.rs} (100%) rename xsd-parser-types/src/xml/{hexbinary.rs => hex.rs} (100%) diff --git a/xsd-parser-types/src/xml/base64binary.rs b/xsd-parser-types/src/xml/base64.rs similarity index 100% rename from xsd-parser-types/src/xml/base64binary.rs rename to xsd-parser-types/src/xml/base64.rs diff --git a/xsd-parser-types/src/xml/hexbinary.rs b/xsd-parser-types/src/xml/hex.rs similarity index 100% rename from xsd-parser-types/src/xml/hexbinary.rs rename to xsd-parser-types/src/xml/hex.rs diff --git a/xsd-parser-types/src/xml/mod.rs b/xsd-parser-types/src/xml/mod.rs index aaa95632..1eb1f62f 100644 --- a/xsd-parser-types/src/xml/mod.rs +++ b/xsd-parser-types/src/xml/mod.rs @@ -4,9 +4,9 @@ mod any_simple_type; mod attributes; -mod base64binary; +mod base64; mod element; -mod hexbinary; +mod hex; mod mixed; mod namespace_scope; mod namespaces; @@ -15,8 +15,8 @@ mod qname; mod text; mod value; -pub use self::base64binary::{Base64Binary as Base64BinaryBytes, Base64String}; -pub use self::hexbinary::{HexBinary, HexString}; +pub use self::base64::{Base64Binary as Base64BinaryBytes, Base64String}; +pub use self::hex::{HexBinary, HexString}; pub use self::any_simple_type::{AnySimpleType, Base64Binary, Decimal, Integer, Unsigned}; pub use self::attributes::{ From bab2180a691c3dc86c2ef84d28e5cad61b4ece70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Oliveira?= Date: Tue, 21 Apr 2026 14:51:50 +0100 Subject: [PATCH 6/7] Fix PR Comments --- xsd-parser-types/src/xml/any_simple_type.rs | 16 ++++---- xsd-parser-types/src/xml/base64.rs | 37 +++++++++++++++---- xsd-parser-types/src/xml/hex.rs | 16 +++++++- xsd-parser-types/src/xml/mod.rs | 4 +- xsd-parser/Cargo.toml | 3 ++ xsd-parser/src/config/mod.rs | 2 +- xsd-parser/tests/feature/facets/mod.rs | 2 + .../feature/facets_binary/expected/default.rs | 20 +++++----- .../facets_binary/expected/quick_xml.rs | 22 +++++------ .../facets_binary/expected/serde_quick_xml.rs | 20 +++++----- .../facets_binary/expected/serde_xml_rs.rs | 20 +++++----- xsd-parser/tests/feature/facets_binary/mod.rs | 9 ++++- 12 files changed, 108 insertions(+), 63 deletions(-) diff --git a/xsd-parser-types/src/xml/any_simple_type.rs b/xsd-parser-types/src/xml/any_simple_type.rs index 7859817c..9b906747 100644 --- a/xsd-parser-types/src/xml/any_simple_type.rs +++ b/xsd-parser-types/src/xml/any_simple_type.rs @@ -10,6 +10,9 @@ use num::{BigInt, BigRational, BigUint}; #[cfg(feature = "quick-xml")] use quick_xml::events::Event; +use crate::quick_xml::{DeserializeBytes, SerializeBytes}; +use crate::xml::NamespacesShared; + #[cfg(feature = "quick-xml")] use crate::{ misc::{Namespace, NamespacePrefix}, @@ -19,10 +22,6 @@ use crate::{ SerializeHelper, Serializer, WithDeserializer, WithSerializer, }, }; -use crate::{ - quick_xml::{DeserializeBytes, SerializeBytes}, - xml::NamespacesShared, -}; use super::QName; @@ -45,10 +44,10 @@ pub type Unsigned = BigUint; pub type Unsigned = usize; #[cfg(feature = "base64")] -pub type Base64Binary = Vec; +type Base64Binary = crate::xml::Base64Binary; #[cfg(not(feature = "base64"))] -pub type Base64Binary = String; +type Base64Binary = crate::xml::Base64String; /// Type that represents an `xs:anySimpleType` value. #[derive(Debug, Clone)] @@ -599,14 +598,15 @@ fn parse_base64_binary(bytes: &str) -> Result { Ok(BASE64_STANDARD .decode(bytes) - .map_err(|_| ErrorKind::InvalidData(bytes.as_bytes().to_vec().into()))?) + .map_err(|_| ErrorKind::InvalidData(bytes.as_bytes().to_vec().into()))? + .into()) } #[inline] #[cfg(not(feature = "base64"))] #[allow(clippy::unnecessary_wraps)] fn parse_base64_binary(s: &str) -> Result { - Ok(s.to_string()) + Ok(s.to_string().into()) } fn format_vec(items: &[X]) -> String { diff --git a/xsd-parser-types/src/xml/base64.rs b/xsd-parser-types/src/xml/base64.rs index 096baeac..1836d0d1 100644 --- a/xsd-parser-types/src/xml/base64.rs +++ b/xsd-parser-types/src/xml/base64.rs @@ -1,12 +1,12 @@ -use std::borrow::Cow; use std::ops::Deref; +use std::{borrow::Cow, ops::DerefMut}; #[cfg(feature = "quick-xml")] use crate::quick_xml::{ DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, }; -#[cfg(any(feature = "quick-xml", feature = "serde"))] +#[cfg(all(feature = "base64", any(feature = "quick-xml", feature = "serde")))] use base64::{engine::general_purpose, Engine as _}; /// Wrapper for base64Binary encoded as a String. @@ -55,6 +55,12 @@ impl Deref for Base64String { } } +impl DerefMut for Base64String { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + #[cfg(feature = "quick-xml")] impl SerializeBytes for Base64String { fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { @@ -74,15 +80,32 @@ impl DeserializeBytes for Base64String { #[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct Base64Binary(pub Vec); +impl From> for Base64Binary { + fn from(value: Vec) -> Self { + Self(value) + } +} + +impl From for Vec { + fn from(value: Base64Binary) -> Self { + value.0 + } +} + impl Deref for Base64Binary { - type Target = [u8]; + type Target = Vec; fn deref(&self) -> &Self::Target { &self.0 } } +impl DerefMut for Base64Binary { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} -#[cfg(feature = "quick-xml")] +#[cfg(all(feature = "base64", feature = "quick-xml"))] impl SerializeBytes for Base64Binary { fn serialize_bytes( &self, @@ -93,7 +116,7 @@ impl SerializeBytes for Base64Binary { } } -#[cfg(feature = "quick-xml")] +#[cfg(all(feature = "base64", feature = "quick-xml"))] impl DeserializeBytes for Base64Binary { fn deserialize_bytes(_helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { let inner = general_purpose::STANDARD @@ -103,7 +126,7 @@ impl DeserializeBytes for Base64Binary { } } -#[cfg(feature = "serde")] +#[cfg(all(feature = "base64", feature = "serde"))] impl serde::Serialize for Base64Binary { fn serialize(&self, serializer: S) -> Result where @@ -114,7 +137,7 @@ impl serde::Serialize for Base64Binary { } } -#[cfg(feature = "serde")] +#[cfg(all(feature = "base64", feature = "serde"))] impl<'de> serde::Deserialize<'de> for Base64Binary { fn deserialize(deserializer: D) -> Result where diff --git a/xsd-parser-types/src/xml/hex.rs b/xsd-parser-types/src/xml/hex.rs index 7df62f63..1ecfd6be 100644 --- a/xsd-parser-types/src/xml/hex.rs +++ b/xsd-parser-types/src/xml/hex.rs @@ -1,5 +1,5 @@ -use std::borrow::Cow; use std::ops::Deref; +use std::{borrow::Cow, ops::DerefMut}; #[cfg(feature = "quick-xml")] use crate::quick_xml::{ @@ -51,6 +51,12 @@ impl Deref for HexString { } } +impl DerefMut for HexString { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + #[cfg(feature = "quick-xml")] impl SerializeBytes for HexString { fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { @@ -71,13 +77,19 @@ impl DeserializeBytes for HexString { pub struct HexBinary(pub Vec); impl Deref for HexBinary { - type Target = [u8]; + type Target = Vec; fn deref(&self) -> &Self::Target { &self.0 } } +impl DerefMut for HexBinary { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + #[cfg(feature = "quick-xml")] impl SerializeBytes for HexBinary { fn serialize_bytes( diff --git a/xsd-parser-types/src/xml/mod.rs b/xsd-parser-types/src/xml/mod.rs index 1eb1f62f..f2f09c34 100644 --- a/xsd-parser-types/src/xml/mod.rs +++ b/xsd-parser-types/src/xml/mod.rs @@ -15,10 +15,10 @@ mod qname; mod text; mod value; -pub use self::base64::{Base64Binary as Base64BinaryBytes, Base64String}; +pub use self::base64::{Base64Binary, Base64String}; pub use self::hex::{HexBinary, HexString}; -pub use self::any_simple_type::{AnySimpleType, Base64Binary, Decimal, Integer, Unsigned}; +pub use self::any_simple_type::{AnySimpleType, Decimal, Integer, Unsigned}; pub use self::attributes::{ AnyAttributes, Attributes, Key as AttributeKey, Value as AttributeValue, }; diff --git a/xsd-parser/Cargo.toml b/xsd-parser/Cargo.toml index ba3e935c..679ba80c 100644 --- a/xsd-parser/Cargo.toml +++ b/xsd-parser/Cargo.toml @@ -17,6 +17,9 @@ all-features = true # Enable support for web resolvers web-resolver = [ "reqwest" ] +# Enable support for base64 encoding/decoding +base64 = ["xsd-parser-types/base64"] + # Helper feature to automatically update all code expectations of the tests update-expectations = [ ] diff --git a/xsd-parser/src/config/mod.rs b/xsd-parser/src/config/mod.rs index efbe5f53..cee926fe 100644 --- a/xsd-parser/src/config/mod.rs +++ b/xsd-parser/src/config/mod.rs @@ -560,7 +560,7 @@ impl Config { /// Add a type definition for `xs:base64Binary` that uses the `xsd_parser_types::xml::Base64Binary` type. pub fn with_base64binary_type(self) -> Self { - self.with_base64binary_type_from("::xsd_parser_types::xml::Base64BinaryBytes") + self.with_base64binary_type_from("::xsd_parser_types::xml::Base64Binary") } /// Add a type definition for `xs:Base64Binary` that uses the type defined at the passed `path`. diff --git a/xsd-parser/tests/feature/facets/mod.rs b/xsd-parser/tests/feature/facets/mod.rs index b13c0c6e..c1693b44 100644 --- a/xsd-parser/tests/feature/facets/mod.rs +++ b/xsd-parser/tests/feature/facets/mod.rs @@ -1,3 +1,5 @@ +#![cfg(not(feature = "base64"))] + use xsd_parser::{ config::{OptimizerFlags, SerdeXmlRsVersion}, Config, IdentType, diff --git a/xsd-parser/tests/feature/facets_binary/expected/default.rs b/xsd-parser/tests/feature/facets_binary/expected/default.rs index e5e8d507..f64c5fb3 100644 --- a/xsd-parser/tests/feature/facets_binary/expected/default.rs +++ b/xsd-parser/tests/feature/facets_binary/expected/default.rs @@ -3,7 +3,7 @@ use regex::Regex; use std::sync::LazyLock; use xsd_parser_types::{ quick_xml::{fraction_digits, ValidateError}, - xml::{Base64BinaryBytes, HexBinary}, + xml::{Base64Binary, HexBinary}, }; pub type Root = RootType; #[derive(Debug)] @@ -191,17 +191,17 @@ impl Deref for HexType { } } #[derive(Debug)] -pub struct Base64Type(pub Base64BinaryBytes); +pub struct Base64Type(pub Base64Binary); impl Base64Type { - pub fn new(inner: Base64BinaryBytes) -> Result { + pub fn new(inner: Base64Binary) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> Base64BinaryBytes { + pub fn into_inner(self) -> Base64Binary { self.0 } - pub fn validate_value(value: &Base64BinaryBytes) -> Result<(), ValidateError> { + pub fn validate_value(value: &Base64Binary) -> Result<(), ValidateError> { if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } @@ -211,19 +211,19 @@ impl Base64Type { Ok(()) } } -impl From for Base64BinaryBytes { - fn from(value: Base64Type) -> Base64BinaryBytes { +impl From for Base64Binary { + fn from(value: Base64Type) -> Base64Binary { value.0 } } -impl TryFrom for Base64Type { +impl TryFrom for Base64Type { type Error = ValidateError; - fn try_from(value: Base64BinaryBytes) -> Result { + fn try_from(value: Base64Binary) -> Result { Self::new(value) } } impl Deref for Base64Type { - type Target = Base64BinaryBytes; + type Target = Base64Binary; fn deref(&self) -> &Self::Target { &self.0 } diff --git a/xsd-parser/tests/feature/facets_binary/expected/quick_xml.rs b/xsd-parser/tests/feature/facets_binary/expected/quick_xml.rs index 81290fe9..913e7939 100644 --- a/xsd-parser/tests/feature/facets_binary/expected/quick_xml.rs +++ b/xsd-parser/tests/feature/facets_binary/expected/quick_xml.rs @@ -8,7 +8,7 @@ use xsd_parser_types::{ SerializeBytes, SerializeHelper, ValidateError, WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, WithSerializer, }, - xml::{Base64BinaryBytes, HexBinary}, + xml::{Base64Binary, HexBinary}, }; pub const NS_XS: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema"); pub const NS_XML: Namespace = Namespace::new_const(b"http://www.w3.org/XML/1998/namespace"); @@ -302,17 +302,17 @@ impl DeserializeBytes for HexType { } impl WithDeserializerFromBytes for HexType {} #[derive(Debug)] -pub struct Base64Type(pub Base64BinaryBytes); +pub struct Base64Type(pub Base64Binary); impl Base64Type { - pub fn new(inner: Base64BinaryBytes) -> Result { + pub fn new(inner: Base64Binary) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> Base64BinaryBytes { + pub fn into_inner(self) -> Base64Binary { self.0 } - pub fn validate_value(value: &Base64BinaryBytes) -> Result<(), ValidateError> { + pub fn validate_value(value: &Base64Binary) -> Result<(), ValidateError> { if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } @@ -322,19 +322,19 @@ impl Base64Type { Ok(()) } } -impl From for Base64BinaryBytes { - fn from(value: Base64Type) -> Base64BinaryBytes { +impl From for Base64Binary { + fn from(value: Base64Type) -> Base64Binary { value.0 } } -impl TryFrom for Base64Type { +impl TryFrom for Base64Type { type Error = ValidateError; - fn try_from(value: Base64BinaryBytes) -> Result { + fn try_from(value: Base64Binary) -> Result { Self::new(value) } } impl Deref for Base64Type { - type Target = Base64BinaryBytes; + type Target = Base64Binary; fn deref(&self) -> &Self::Target { &self.0 } @@ -347,7 +347,7 @@ impl SerializeBytes for Base64Type { impl WithSerializeToBytes for Base64Type {} impl DeserializeBytes for Base64Type { fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { - let inner = Base64BinaryBytes::deserialize_bytes(helper, bytes)?; + let inner = Base64Binary::deserialize_bytes(helper, bytes)?; Ok(Self::new(inner).map_err(|error| (bytes, error))?) } } diff --git a/xsd-parser/tests/feature/facets_binary/expected/serde_quick_xml.rs b/xsd-parser/tests/feature/facets_binary/expected/serde_quick_xml.rs index f51a2f5d..1b0dc893 100644 --- a/xsd-parser/tests/feature/facets_binary/expected/serde_quick_xml.rs +++ b/xsd-parser/tests/feature/facets_binary/expected/serde_quick_xml.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use std::sync::LazyLock; use xsd_parser_types::{ quick_xml::{fraction_digits, ValidateError}, - xml::{Base64BinaryBytes, HexBinary}, + xml::{Base64Binary, HexBinary}, }; pub type Root = RootType; #[derive(Debug, Deserialize, Serialize)] @@ -198,17 +198,17 @@ impl Deref for HexType { } } #[derive(Debug, Deserialize, Serialize)] -pub struct Base64Type(pub Base64BinaryBytes); +pub struct Base64Type(pub Base64Binary); impl Base64Type { - pub fn new(inner: Base64BinaryBytes) -> Result { + pub fn new(inner: Base64Binary) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> Base64BinaryBytes { + pub fn into_inner(self) -> Base64Binary { self.0 } - pub fn validate_value(value: &Base64BinaryBytes) -> Result<(), ValidateError> { + pub fn validate_value(value: &Base64Binary) -> Result<(), ValidateError> { if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } @@ -218,19 +218,19 @@ impl Base64Type { Ok(()) } } -impl From for Base64BinaryBytes { - fn from(value: Base64Type) -> Base64BinaryBytes { +impl From for Base64Binary { + fn from(value: Base64Type) -> Base64Binary { value.0 } } -impl TryFrom for Base64Type { +impl TryFrom for Base64Type { type Error = ValidateError; - fn try_from(value: Base64BinaryBytes) -> Result { + fn try_from(value: Base64Binary) -> Result { Self::new(value) } } impl Deref for Base64Type { - type Target = Base64BinaryBytes; + type Target = Base64Binary; fn deref(&self) -> &Self::Target { &self.0 } diff --git a/xsd-parser/tests/feature/facets_binary/expected/serde_xml_rs.rs b/xsd-parser/tests/feature/facets_binary/expected/serde_xml_rs.rs index 3dcbe9bc..e71c48ef 100644 --- a/xsd-parser/tests/feature/facets_binary/expected/serde_xml_rs.rs +++ b/xsd-parser/tests/feature/facets_binary/expected/serde_xml_rs.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use std::sync::LazyLock; use xsd_parser_types::{ quick_xml::{fraction_digits, ValidateError}, - xml::{Base64BinaryBytes, HexBinary}, + xml::{Base64Binary, HexBinary}, }; pub type Root = RootType; #[derive(Debug, Deserialize, Serialize)] @@ -198,17 +198,17 @@ impl Deref for HexType { } } #[derive(Debug, Deserialize, Serialize)] -pub struct Base64Type(pub Base64BinaryBytes); +pub struct Base64Type(pub Base64Binary); impl Base64Type { - pub fn new(inner: Base64BinaryBytes) -> Result { + pub fn new(inner: Base64Binary) -> Result { Self::validate_value(&inner)?; Ok(Self(inner)) } #[must_use] - pub fn into_inner(self) -> Base64BinaryBytes { + pub fn into_inner(self) -> Base64Binary { self.0 } - pub fn validate_value(value: &Base64BinaryBytes) -> Result<(), ValidateError> { + pub fn validate_value(value: &Base64Binary) -> Result<(), ValidateError> { if value.len() < 16usize { return Err(ValidateError::MinLength(16usize)); } @@ -218,19 +218,19 @@ impl Base64Type { Ok(()) } } -impl From for Base64BinaryBytes { - fn from(value: Base64Type) -> Base64BinaryBytes { +impl From for Base64Binary { + fn from(value: Base64Type) -> Base64Binary { value.0 } } -impl TryFrom for Base64Type { +impl TryFrom for Base64Type { type Error = ValidateError; - fn try_from(value: Base64BinaryBytes) -> Result { + fn try_from(value: Base64Binary) -> Result { Self::new(value) } } impl Deref for Base64Type { - type Target = Base64BinaryBytes; + type Target = Base64Binary; fn deref(&self) -> &Self::Target { &self.0 } diff --git a/xsd-parser/tests/feature/facets_binary/mod.rs b/xsd-parser/tests/feature/facets_binary/mod.rs index 070f5797..9d7430ed 100644 --- a/xsd-parser/tests/feature/facets_binary/mod.rs +++ b/xsd-parser/tests/feature/facets_binary/mod.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "base64")] + use xsd_parser::{ config::{OptimizerFlags, SerdeXmlRsVersion}, Config, IdentType, @@ -25,7 +27,7 @@ macro_rules! check_obj { assert!(matches!(it.next(), Some(RootTypeContent::PositiveDecimal(x)) if x.eq(&0.01_f64))); assert!(matches!(it.next(), Some(RootTypeContent::RestrictedString(x)) if *x == "Abcdef")); assert!(matches!(it.next(), Some(RootTypeContent::HexType(x)) if x.0 == xsd_parser_types::xml::HexBinary(const_hex::decode("a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9").unwrap()))); - assert!(matches!(it.next(), Some(RootTypeContent::Base64Type(x)) if *x == xsd_parser_types::xml::Base64BinaryBytes(b"ABCDEFGHIJKLMNOP".to_vec()))); + assert!(matches!(it.next(), Some(RootTypeContent::Base64Type(x)) if *x == xsd_parser_types::xml::Base64Binary(b"ABCDEFGHIJKLMNOP".to_vec()))); assert!(it.next().is_none()); }}; } @@ -43,7 +45,7 @@ macro_rules! test_obj { RootTypeContent::HexType(HexType(xsd_parser_types::xml::HexBinary( const_hex::decode("a1f3e8b2c9d4f6e7a2b3c4d5e6f7a8b9").unwrap(), ))), - RootTypeContent::Base64Type(Base64Type(xsd_parser_types::xml::Base64BinaryBytes( + RootTypeContent::Base64Type(Base64Type(xsd_parser_types::xml::Base64Binary( b"ABCDEFGHIJKLMNOP".to_vec(), ))), ], @@ -72,6 +74,7 @@ mod default { /* quick_xml */ #[test] +#[cfg(feature = "base64")] fn generate_quick_xml() { generate_test( "tests/feature/facets_binary/schema.xsd", @@ -82,6 +85,7 @@ fn generate_quick_xml() { #[test] #[cfg(not(feature = "update-expectations"))] +#[cfg(feature = "base64")] fn read_quick_xml() { use quick_xml::RootType; @@ -94,6 +98,7 @@ fn read_quick_xml() { #[test] #[cfg(not(feature = "update-expectations"))] +#[cfg(feature = "base64")] fn write_quick_xml() { let obj = test_obj!(quick_xml); From 6e5a1c5a71fb14ded55afa42c0208e550cf97524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Oliveira?= Date: Thu, 23 Apr 2026 11:51:27 +0000 Subject: [PATCH 7/7] Make HexString and Base64String the default --- xsd-parser-types/src/xml/base64.rs | 23 ++ xsd-parser-types/src/xml/hex.rs | 23 ++ xsd-parser/src/pipeline/interpreter/mod.rs | 24 +- .../absolute_paths/expected/default.rs | 4 +- .../absolute_paths/expected/quick_xml.rs | 4 +- .../feature/build_in/expected/default.rs | 5 +- .../feature/build_in/expected/quick_xml.rs | 5 +- .../build_in/expected/serde_quick_xml.rs | 5 +- .../feature/build_in/expected/serde_xml_rs.rs | 5 +- .../duplicate_idents/expected/default.rs | 5 +- .../duplicate_idents/expected/quick_xml.rs | 13 +- .../empty_string/expected/quick_xml.rs | 5 +- .../empty_string/expected/serde_quick_xml.rs | 5 +- .../empty_string/expected/serde_xml_rs_v7.rs | 5 +- .../empty_string/expected/serde_xml_rs_v8.rs | 5 +- xsd-parser/tests/feature/facets/mod.rs | 2 - .../expected/default.rs | 5 +- .../factur_x/expected/en16931_default.rs | 3 +- .../factur_x/expected/en16931_quick_xml.rs | 33 ++- .../factur_x/expected/extended_default.rs | 3 +- .../factur_x/expected/extended_quick_xml.rs | 33 ++- .../expected/default.rs | 37 +-- .../expected/quick_xml.rs | 270 ++++++++++-------- .../expected/serde_quick_xml.rs | 37 +-- .../expected/serde_xml_rs_v7.rs | 37 +-- .../tests/schema/musicxml/expected/default.rs | 4 +- .../schema/musicxml/expected/quick_xml.rs | 4 +- .../tests/schema/ofd/expected/default.rs | 8 +- .../tests/schema/ofd/expected/quick_xml.rs | 56 ++-- .../schema/opendrive/v1_4/expected/default.rs | 5 +- .../schema/opendrive/v1_6/expected/default.rs | 5 +- .../schema/xml_catalogs/expected/default.rs | 5 +- .../schema/xml_catalogs/expected/quick_xml.rs | 13 +- .../xml_catalogs/expected/serde_quick_xml.rs | 5 +- .../xml_catalogs/expected/serde_xml_rs.rs | 5 +- 35 files changed, 420 insertions(+), 286 deletions(-) diff --git a/xsd-parser-types/src/xml/base64.rs b/xsd-parser-types/src/xml/base64.rs index 1836d0d1..7d98a2e0 100644 --- a/xsd-parser-types/src/xml/base64.rs +++ b/xsd-parser-types/src/xml/base64.rs @@ -1,9 +1,12 @@ +use std::convert::Infallible; use std::ops::Deref; +use std::str::FromStr; use std::{borrow::Cow, ops::DerefMut}; #[cfg(feature = "quick-xml")] use crate::quick_xml::{ DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, + WithDeserializerFromBytes, WithSerializeToBytes, }; #[cfg(all(feature = "base64", any(feature = "quick-xml", feature = "serde")))] @@ -47,6 +50,14 @@ impl From for String { } } +impl FromStr for Base64String { + type Err = Infallible; + + fn from_str(value: &str) -> Result { + Ok(Self(value.to_owned())) + } +} + impl Deref for Base64String { type Target = String; @@ -76,6 +87,12 @@ impl DeserializeBytes for Base64String { } } +#[cfg(feature = "quick-xml")] +impl WithSerializeToBytes for Base64String {} + +#[cfg(feature = "quick-xml")] +impl WithDeserializerFromBytes for Base64String {} + /// Wrapper for base64Binary as decoded bytes. #[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct Base64Binary(pub Vec); @@ -126,6 +143,12 @@ impl DeserializeBytes for Base64Binary { } } +#[cfg(all(feature = "base64", feature = "quick-xml"))] +impl WithSerializeToBytes for Base64Binary {} + +#[cfg(all(feature = "base64", feature = "quick-xml"))] +impl WithDeserializerFromBytes for Base64Binary {} + #[cfg(all(feature = "base64", feature = "serde"))] impl serde::Serialize for Base64Binary { fn serialize(&self, serializer: S) -> Result diff --git a/xsd-parser-types/src/xml/hex.rs b/xsd-parser-types/src/xml/hex.rs index 1ecfd6be..dca4a134 100644 --- a/xsd-parser-types/src/xml/hex.rs +++ b/xsd-parser-types/src/xml/hex.rs @@ -1,9 +1,12 @@ +use std::convert::Infallible; use std::ops::Deref; +use std::str::FromStr; use std::{borrow::Cow, ops::DerefMut}; #[cfg(feature = "quick-xml")] use crate::quick_xml::{ DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, + WithDeserializerFromBytes, WithSerializeToBytes, }; /// Wrapper for hexBinary encoded as String. @@ -43,6 +46,14 @@ impl From for String { } } +impl FromStr for HexString { + type Err = Infallible; + + fn from_str(value: &str) -> Result { + Ok(Self(value.to_owned())) + } +} + impl Deref for HexString { type Target = String; @@ -72,6 +83,12 @@ impl DeserializeBytes for HexString { } } +#[cfg(feature = "quick-xml")] +impl WithSerializeToBytes for HexString {} + +#[cfg(feature = "quick-xml")] +impl WithDeserializerFromBytes for HexString {} + /// Wrapper for hexBinary as decoded bytes. #[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct HexBinary(pub Vec); @@ -109,6 +126,12 @@ impl DeserializeBytes for HexBinary { } } +#[cfg(feature = "quick-xml")] +impl WithSerializeToBytes for HexBinary {} + +#[cfg(feature = "quick-xml")] +impl WithDeserializerFromBytes for HexBinary {} + #[cfg(feature = "serde")] impl serde::Serialize for HexBinary { fn serialize(&self, serializer: S) -> Result diff --git a/xsd-parser/src/pipeline/interpreter/mod.rs b/xsd-parser/src/pipeline/interpreter/mod.rs index 27adaa27..eb0606f7 100644 --- a/xsd-parser/src/pipeline/interpreter/mod.rs +++ b/xsd-parser/src/pipeline/interpreter/mod.rs @@ -196,6 +196,18 @@ impl<'a> Interpreter<'a> { )?; }}; } + macro_rules! add_custom { + ($src:expr, $dst:expr, $default:expr) => {{ + let src = TypeIdent::type_($src).with_ns(xs); + let dst = TypeIdent::type_($dst).with_ns(NamespaceId::ANONYMOUS); + let ty = CustomMeta::new($dst) + .include_from(concat!("::xsd_parser_types::xml::", $dst)) + .with_default($default); + + self.state.add_type(dst.clone(), ty)?; + self.state.add_type(src, ReferenceMeta::new(dst))?; + }}; + } /* Primitive Types */ @@ -219,8 +231,16 @@ impl<'a> Interpreter<'a> { /* Data related types */ - add!("hexBinary", STRING); - add!("base64Binary", STRING); + add_custom!( + "hexBinary", + "HexString", + make_from_str_value_generator("::xsd_parser_types::xml::HexString") + ); + add_custom!( + "base64Binary", + "Base64String", + make_from_str_value_generator("::xsd_parser_types::xml::Base64String") + ); /* URL related types */ diff --git a/xsd-parser/tests/feature/absolute_paths/expected/default.rs b/xsd-parser/tests/feature/absolute_paths/expected/default.rs index 914727cf..b59302fc 100644 --- a/xsd-parser/tests/feature/absolute_paths/expected/default.rs +++ b/xsd-parser/tests/feature/absolute_paths/expected/default.rs @@ -90,7 +90,7 @@ pub type AnySimpleType = ::std::string::String; #[derive(Debug)] pub struct AnyType; pub type AnyUriType = ::std::string::String; -pub type Base64BinaryType = ::std::string::String; +pub type Base64BinaryType = ::xsd_parser_types::xml::Base64String; pub type BooleanType = ::core::primitive::bool; pub type ByteType = ::core::primitive::i8; pub type DateType = ::std::string::String; @@ -104,7 +104,7 @@ pub type GMonthType = ::std::string::String; pub type GMonthDayType = ::std::string::String; pub type GYearType = ::std::string::String; pub type GYearMonthType = ::std::string::String; -pub type HexBinaryType = ::std::string::String; +pub type HexBinaryType = ::xsd_parser_types::xml::HexString; pub type IntType = ::core::primitive::i32; pub type IntegerType = ::core::primitive::i32; pub type LanguageType = ::std::string::String; diff --git a/xsd-parser/tests/feature/absolute_paths/expected/quick_xml.rs b/xsd-parser/tests/feature/absolute_paths/expected/quick_xml.rs index 2ee0e281..4349a2cc 100644 --- a/xsd-parser/tests/feature/absolute_paths/expected/quick_xml.rs +++ b/xsd-parser/tests/feature/absolute_paths/expected/quick_xml.rs @@ -241,7 +241,7 @@ impl ::xsd_parser_types::quick_xml::WithDeserializer for AnyType { type Deserializer = quick_xml_deserialize::AnyTypeDeserializer; } pub type AnyUriType = ::std::string::String; -pub type Base64BinaryType = ::std::string::String; +pub type Base64BinaryType = ::xsd_parser_types::xml::Base64String; pub type BooleanType = ::core::primitive::bool; pub type ByteType = ::core::primitive::i8; pub type DateType = ::std::string::String; @@ -255,7 +255,7 @@ pub type GMonthType = ::std::string::String; pub type GMonthDayType = ::std::string::String; pub type GYearType = ::std::string::String; pub type GYearMonthType = ::std::string::String; -pub type HexBinaryType = ::std::string::String; +pub type HexBinaryType = ::xsd_parser_types::xml::HexString; pub type IntType = ::core::primitive::i32; pub type IntegerType = ::core::primitive::i32; pub type LanguageType = ::std::string::String; diff --git a/xsd-parser/tests/feature/build_in/expected/default.rs b/xsd-parser/tests/feature/build_in/expected/default.rs index c5d8c472..6565873c 100644 --- a/xsd-parser/tests/feature/build_in/expected/default.rs +++ b/xsd-parser/tests/feature/build_in/expected/default.rs @@ -1,3 +1,4 @@ +use xsd_parser_types::xml::{Base64String, HexString}; #[derive(Debug, Default)] pub struct EntitiesType(pub Vec); pub type EntityType = String; @@ -16,7 +17,7 @@ pub type AnySimpleType = String; #[derive(Debug)] pub struct AnyType; pub type AnyUriType = String; -pub type Base64BinaryType = String; +pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -30,7 +31,7 @@ pub type GMonthType = String; pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; -pub type HexBinaryType = String; +pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/build_in/expected/quick_xml.rs b/xsd-parser/tests/feature/build_in/expected/quick_xml.rs index 76ad57a3..27215fce 100644 --- a/xsd-parser/tests/feature/build_in/expected/quick_xml.rs +++ b/xsd-parser/tests/feature/build_in/expected/quick_xml.rs @@ -5,6 +5,7 @@ use xsd_parser_types::{ DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, WithSerializer, }, + xml::{Base64String, HexString}, }; pub const NS_XS: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema"); pub const NS_XML: Namespace = Namespace::new_const(b"http://www.w3.org/XML/1998/namespace"); @@ -120,7 +121,7 @@ impl WithDeserializer for AnyType { type Deserializer = quick_xml_deserialize::AnyTypeDeserializer; } pub type AnyUriType = String; -pub type Base64BinaryType = String; +pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -134,7 +135,7 @@ pub type GMonthType = String; pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; -pub type HexBinaryType = String; +pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/build_in/expected/serde_quick_xml.rs b/xsd-parser/tests/feature/build_in/expected/serde_quick_xml.rs index 4a235bb8..5b71aab8 100644 --- a/xsd-parser/tests/feature/build_in/expected/serde_quick_xml.rs +++ b/xsd-parser/tests/feature/build_in/expected/serde_quick_xml.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use xsd_parser_types::xml::{Base64String, HexString}; #[derive(Debug, Default, Deserialize, Serialize)] pub struct EntitiesType(pub Vec); pub type EntityType = String; @@ -17,7 +18,7 @@ pub type AnySimpleType = String; #[derive(Debug, Deserialize, Serialize)] pub struct AnyType; pub type AnyUriType = String; -pub type Base64BinaryType = String; +pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -31,7 +32,7 @@ pub type GMonthType = String; pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; -pub type HexBinaryType = String; +pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/build_in/expected/serde_xml_rs.rs b/xsd-parser/tests/feature/build_in/expected/serde_xml_rs.rs index 4a235bb8..5b71aab8 100644 --- a/xsd-parser/tests/feature/build_in/expected/serde_xml_rs.rs +++ b/xsd-parser/tests/feature/build_in/expected/serde_xml_rs.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use xsd_parser_types::xml::{Base64String, HexString}; #[derive(Debug, Default, Deserialize, Serialize)] pub struct EntitiesType(pub Vec); pub type EntityType = String; @@ -17,7 +18,7 @@ pub type AnySimpleType = String; #[derive(Debug, Deserialize, Serialize)] pub struct AnyType; pub type AnyUriType = String; -pub type Base64BinaryType = String; +pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -31,7 +32,7 @@ pub type GMonthType = String; pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; -pub type HexBinaryType = String; +pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/duplicate_idents/expected/default.rs b/xsd-parser/tests/feature/duplicate_idents/expected/default.rs index 13abb067..c31f6848 100644 --- a/xsd-parser/tests/feature/duplicate_idents/expected/default.rs +++ b/xsd-parser/tests/feature/duplicate_idents/expected/default.rs @@ -23,6 +23,7 @@ pub mod foo { } } pub mod xs { + use xsd_parser_types::xml::{Base64String, HexString}; #[derive(Debug, Default)] pub struct EntitiesType(pub Vec); pub type EntityType = String; @@ -41,7 +42,7 @@ pub mod xs { #[derive(Debug)] pub struct AnyType; pub type AnyUriType = String; - pub type Base64BinaryType = String; + pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -55,7 +56,7 @@ pub mod xs { pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; - pub type HexBinaryType = String; + pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/duplicate_idents/expected/quick_xml.rs b/xsd-parser/tests/feature/duplicate_idents/expected/quick_xml.rs index b2dd1fb5..6b6f3f6e 100644 --- a/xsd-parser/tests/feature/duplicate_idents/expected/quick_xml.rs +++ b/xsd-parser/tests/feature/duplicate_idents/expected/quick_xml.rs @@ -1094,9 +1094,12 @@ pub mod foo { } pub mod xs { use std::borrow::Cow; - use xsd_parser_types::quick_xml::{ - DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, - WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, WithSerializer, + use xsd_parser_types::{ + quick_xml::{ + DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, + WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, WithSerializer, + }, + xml::{Base64String, HexString}, }; #[derive(Debug, Default)] pub struct EntitiesType(pub Vec); @@ -1215,7 +1218,7 @@ pub mod xs { type Deserializer = quick_xml_deserialize::AnyTypeDeserializer; } pub type AnyUriType = String; - pub type Base64BinaryType = String; + pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -1229,7 +1232,7 @@ pub mod xs { pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; - pub type HexBinaryType = String; + pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/empty_string/expected/quick_xml.rs b/xsd-parser/tests/feature/empty_string/expected/quick_xml.rs index ec3c5160..81f0e81a 100644 --- a/xsd-parser/tests/feature/empty_string/expected/quick_xml.rs +++ b/xsd-parser/tests/feature/empty_string/expected/quick_xml.rs @@ -5,6 +5,7 @@ use xsd_parser_types::{ DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, WithSerializer, }, + xml::{Base64String, HexString}, }; pub const NS_XS: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema"); pub const NS_XML: Namespace = Namespace::new_const(b"http://www.w3.org/XML/1998/namespace"); @@ -168,7 +169,7 @@ impl WithDeserializer for AnyType { type Deserializer = quick_xml_deserialize::AnyTypeDeserializer; } pub type AnyUriType = String; -pub type Base64BinaryType = String; +pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -182,7 +183,7 @@ pub type GMonthType = String; pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; -pub type HexBinaryType = String; +pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/empty_string/expected/serde_quick_xml.rs b/xsd-parser/tests/feature/empty_string/expected/serde_quick_xml.rs index 27626efb..5d34902b 100644 --- a/xsd-parser/tests/feature/empty_string/expected/serde_quick_xml.rs +++ b/xsd-parser/tests/feature/empty_string/expected/serde_quick_xml.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use xsd_parser_types::xml::{Base64String, HexString}; pub type ComplexContent = ComplexContentType; #[derive(Debug, Deserialize, Serialize)] pub struct ComplexContentType { @@ -33,7 +34,7 @@ pub type AnySimpleType = String; #[derive(Debug, Deserialize, Serialize)] pub struct AnyType; pub type AnyUriType = String; -pub type Base64BinaryType = String; +pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -47,7 +48,7 @@ pub type GMonthType = String; pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; -pub type HexBinaryType = String; +pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/empty_string/expected/serde_xml_rs_v7.rs b/xsd-parser/tests/feature/empty_string/expected/serde_xml_rs_v7.rs index 01a40ec1..cf3d1095 100644 --- a/xsd-parser/tests/feature/empty_string/expected/serde_xml_rs_v7.rs +++ b/xsd-parser/tests/feature/empty_string/expected/serde_xml_rs_v7.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use xsd_parser_types::xml::{Base64String, HexString}; pub type ComplexContent = ComplexContentType; #[derive(Debug, Deserialize, Serialize)] pub struct ComplexContentType { @@ -33,7 +34,7 @@ pub type AnySimpleType = String; #[derive(Debug, Deserialize, Serialize)] pub struct AnyType; pub type AnyUriType = String; -pub type Base64BinaryType = String; +pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -47,7 +48,7 @@ pub type GMonthType = String; pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; -pub type HexBinaryType = String; +pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/empty_string/expected/serde_xml_rs_v8.rs b/xsd-parser/tests/feature/empty_string/expected/serde_xml_rs_v8.rs index 46d01480..a9c78aed 100644 --- a/xsd-parser/tests/feature/empty_string/expected/serde_xml_rs_v8.rs +++ b/xsd-parser/tests/feature/empty_string/expected/serde_xml_rs_v8.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use xsd_parser_types::xml::{Base64String, HexString}; pub type ComplexContent = ComplexContentType; #[derive(Debug, Deserialize, Serialize)] pub struct ComplexContentType { @@ -33,7 +34,7 @@ pub type AnySimpleType = String; #[derive(Debug, Deserialize, Serialize)] pub struct AnyType; pub type AnyUriType = String; -pub type Base64BinaryType = String; +pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -47,7 +48,7 @@ pub type GMonthType = String; pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; -pub type HexBinaryType = String; +pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/feature/facets/mod.rs b/xsd-parser/tests/feature/facets/mod.rs index c1693b44..9c5dd8a4 100644 --- a/xsd-parser/tests/feature/facets/mod.rs +++ b/xsd-parser/tests/feature/facets/mod.rs @@ -11,8 +11,6 @@ fn config() -> Config { Config::test_default() .without_optimizer_flags(OptimizerFlags::USE_UNRESTRICTED_BASE_TYPE_SIMPLE) .with_generate([(IdentType::Element, "tns:Root")]) - .with_hexbinary_type_from("::xsd_parser_types::xml::HexString") - .with_base64binary_type_from("::xsd_parser_types::xml::Base64String") } #[cfg(not(feature = "update-expectations"))] diff --git a/xsd-parser/tests/feature/trailing_underscore_group/expected/default.rs b/xsd-parser/tests/feature/trailing_underscore_group/expected/default.rs index 33eb8022..0403659c 100644 --- a/xsd-parser/tests/feature/trailing_underscore_group/expected/default.rs +++ b/xsd-parser/tests/feature/trailing_underscore_group/expected/default.rs @@ -1,3 +1,4 @@ +use xsd_parser_types::xml::{Base64String, HexString}; #[derive(Debug, Default)] pub struct ENTITIESType(pub Vec); pub type ENTITYType = String; @@ -16,7 +17,7 @@ pub type anySimpleTypeType = String; #[derive(Debug)] pub struct anyTypeType; pub type anyURIType = String; -pub type base64BinaryType = String; +pub type base64BinaryType = Base64String; pub type booleanType = bool; pub type byteType = i8; pub type dateType = String; @@ -30,7 +31,7 @@ pub type gMonthType = String; pub type gMonthDayType = String; pub type gYearType = String; pub type gYearMonthType = String; -pub type hexBinaryType = String; +pub type hexBinaryType = HexString; pub type intType = i32; pub type integerType = i32; pub type languageType = String; diff --git a/xsd-parser/tests/schema/factur_x/expected/en16931_default.rs b/xsd-parser/tests/schema/factur_x/expected/en16931_default.rs index a52487f4..3cfb1fac 100644 --- a/xsd-parser/tests/schema/factur_x/expected/en16931_default.rs +++ b/xsd-parser/tests/schema/factur_x/expected/en16931_default.rs @@ -1,3 +1,4 @@ +use xsd_parser_types::xml::Base64String; pub type CrossIndustryInvoice = CrossIndustryInvoiceType; #[derive(Debug)] pub struct CrossIndustryInvoiceType { @@ -302,7 +303,7 @@ pub struct TaxRegistrationType { pub struct BinaryObjectType { pub mime_code: String, pub filename: String, - pub content: String, + pub content: Base64String, } #[derive(Debug)] pub struct ReferenceCodeType { diff --git a/xsd-parser/tests/schema/factur_x/expected/en16931_quick_xml.rs b/xsd-parser/tests/schema/factur_x/expected/en16931_quick_xml.rs index f2317a98..1411a17a 100644 --- a/xsd-parser/tests/schema/factur_x/expected/en16931_quick_xml.rs +++ b/xsd-parser/tests/schema/factur_x/expected/en16931_quick_xml.rs @@ -1,6 +1,7 @@ use xsd_parser_types::{ misc::{Namespace, NamespacePrefix}, quick_xml::{Error, WithDeserializer, WithSerializer}, + xml::Base64String, }; pub const NS_XS: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema"); pub const NS_XML: Namespace = Namespace::new_const(b"http://www.w3.org/XML/1998/namespace"); @@ -1152,7 +1153,7 @@ impl WithDeserializer for TaxRegistrationType { pub struct BinaryObjectType { pub mime_code: String, pub filename: String, - pub content: String, + pub content: Base64String, } impl WithSerializer for BinaryObjectType { type Serializer<'x> = quick_xml_serialize::BinaryObjectTypeSerializer<'x>; @@ -1632,10 +1633,13 @@ impl WithDeserializer for DateTypeDateStringType { } pub mod quick_xml_deserialize { use core::mem::replace; - use xsd_parser_types::quick_xml::{ - BytesStart, ContentDeserializer, DeserializeHelper, Deserializer, DeserializerArtifact, - DeserializerEvent, DeserializerOutput, DeserializerResult, ElementHandlerOutput, Error, - ErrorKind, Event, RawByteStr, WithDeserializer, + use xsd_parser_types::{ + quick_xml::{ + BytesStart, ContentDeserializer, DeserializeHelper, Deserializer, DeserializerArtifact, + DeserializerEvent, DeserializerOutput, DeserializerResult, ElementHandlerOutput, Error, + ErrorKind, Event, RawByteStr, WithDeserializer, + }, + xml::Base64String, }; #[derive(Debug)] pub struct CrossIndustryInvoiceTypeDeserializer { @@ -19155,13 +19159,13 @@ pub mod quick_xml_deserialize { pub struct BinaryObjectTypeDeserializer { mime_code: String, filename: String, - content: Option, + content: Option, state__: Box, } #[derive(Debug)] enum BinaryObjectTypeDeserializerState { Init__, - Content__(::Deserializer), + Content__(::Deserializer), Unknown__, } impl BinaryObjectTypeDeserializer { @@ -19205,7 +19209,7 @@ pub mod quick_xml_deserialize { } Ok(()) } - fn store_content(&mut self, value: String) -> Result<(), Error> { + fn store_content(&mut self, value: Base64String) -> Result<(), Error> { if self.content.is_some() { Err(ErrorKind::DuplicateContent)?; } @@ -19215,7 +19219,7 @@ pub mod quick_xml_deserialize { fn handle_content<'de>( mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, ) -> DeserializerResult<'de, super::BinaryObjectType> { use BinaryObjectTypeDeserializerState as S; let DeserializerOutput { @@ -22534,9 +22538,12 @@ pub mod quick_xml_deserialize { } } pub mod quick_xml_serialize { - use xsd_parser_types::quick_xml::{ - BytesEnd, BytesStart, Error, Event, IterSerializer, SerializeHelper, Serializer, - WithSerializer, + use xsd_parser_types::{ + quick_xml::{ + BytesEnd, BytesStart, Error, Event, IterSerializer, SerializeHelper, Serializer, + WithSerializer, + }, + xml::Base64String, }; #[derive(Debug)] pub struct CrossIndustryInvoiceTypeSerializer<'ser> { @@ -26770,7 +26777,7 @@ pub mod quick_xml_serialize { #[derive(Debug)] pub(super) enum BinaryObjectTypeSerializerState<'ser> { Init__, - Content__(::Serializer<'ser>), + Content__(::Serializer<'ser>), End__, Done__, Phantom__(&'ser ()), diff --git a/xsd-parser/tests/schema/factur_x/expected/extended_default.rs b/xsd-parser/tests/schema/factur_x/expected/extended_default.rs index fda203fa..917cfe75 100644 --- a/xsd-parser/tests/schema/factur_x/expected/extended_default.rs +++ b/xsd-parser/tests/schema/factur_x/expected/extended_default.rs @@ -1,3 +1,4 @@ +use xsd_parser_types::xml::Base64String; pub type CrossIndustryInvoice = CrossIndustryInvoiceType; #[derive(Debug)] pub struct CrossIndustryInvoiceType { @@ -439,7 +440,7 @@ pub struct DeliveryTermsCodeType { pub struct BinaryObjectType { pub mime_code: String, pub filename: String, - pub content: String, + pub content: Base64String, } #[derive(Debug)] pub struct ReferenceCodeType { diff --git a/xsd-parser/tests/schema/factur_x/expected/extended_quick_xml.rs b/xsd-parser/tests/schema/factur_x/expected/extended_quick_xml.rs index 25f44bdb..ca623512 100644 --- a/xsd-parser/tests/schema/factur_x/expected/extended_quick_xml.rs +++ b/xsd-parser/tests/schema/factur_x/expected/extended_quick_xml.rs @@ -1,6 +1,7 @@ use xsd_parser_types::{ misc::{Namespace, NamespacePrefix}, quick_xml::{Error, WithDeserializer, WithSerializer}, + xml::Base64String, }; pub const NS_XS: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema"); pub const NS_XML: Namespace = Namespace::new_const(b"http://www.w3.org/XML/1998/namespace"); @@ -1505,7 +1506,7 @@ impl WithDeserializer for DeliveryTermsCodeType { pub struct BinaryObjectType { pub mime_code: String, pub filename: String, - pub content: String, + pub content: Base64String, } impl WithSerializer for BinaryObjectType { type Serializer<'x> = quick_xml_serialize::BinaryObjectTypeSerializer<'x>; @@ -2164,10 +2165,13 @@ impl WithDeserializer for DateTypeDateStringType { } pub mod quick_xml_deserialize { use core::mem::replace; - use xsd_parser_types::quick_xml::{ - BytesStart, ContentDeserializer, DeserializeHelper, Deserializer, DeserializerArtifact, - DeserializerEvent, DeserializerOutput, DeserializerResult, ElementHandlerOutput, Error, - ErrorKind, Event, RawByteStr, WithDeserializer, + use xsd_parser_types::{ + quick_xml::{ + BytesStart, ContentDeserializer, DeserializeHelper, Deserializer, DeserializerArtifact, + DeserializerEvent, DeserializerOutput, DeserializerResult, ElementHandlerOutput, Error, + ErrorKind, Event, RawByteStr, WithDeserializer, + }, + xml::Base64String, }; #[derive(Debug)] pub struct CrossIndustryInvoiceTypeDeserializer { @@ -29160,13 +29164,13 @@ pub mod quick_xml_deserialize { pub struct BinaryObjectTypeDeserializer { mime_code: String, filename: String, - content: Option, + content: Option, state__: Box, } #[derive(Debug)] enum BinaryObjectTypeDeserializerState { Init__, - Content__(::Deserializer), + Content__(::Deserializer), Unknown__, } impl BinaryObjectTypeDeserializer { @@ -29210,7 +29214,7 @@ pub mod quick_xml_deserialize { } Ok(()) } - fn store_content(&mut self, value: String) -> Result<(), Error> { + fn store_content(&mut self, value: Base64String) -> Result<(), Error> { if self.content.is_some() { Err(ErrorKind::DuplicateContent)?; } @@ -29220,7 +29224,7 @@ pub mod quick_xml_deserialize { fn handle_content<'de>( mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, ) -> DeserializerResult<'de, super::BinaryObjectType> { use BinaryObjectTypeDeserializerState as S; let DeserializerOutput { @@ -34120,9 +34124,12 @@ pub mod quick_xml_deserialize { } } pub mod quick_xml_serialize { - use xsd_parser_types::quick_xml::{ - BytesEnd, BytesStart, Error, Event, IterSerializer, SerializeHelper, Serializer, - WithSerializer, + use xsd_parser_types::{ + quick_xml::{ + BytesEnd, BytesStart, Error, Event, IterSerializer, SerializeHelper, Serializer, + WithSerializer, + }, + xml::Base64String, }; #[derive(Debug)] pub struct CrossIndustryInvoiceTypeSerializer<'ser> { @@ -39948,7 +39955,7 @@ pub mod quick_xml_serialize { #[derive(Debug)] pub(super) enum BinaryObjectTypeSerializerState<'ser> { Init__, - Content__(::Serializer<'ser>), + Content__(::Serializer<'ser>), End__, Done__, Phantom__(&'ser ()), diff --git a/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/default.rs b/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/default.rs index b0270d3a..4f43ee6a 100644 --- a/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/default.rs +++ b/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/default.rs @@ -1,3 +1,4 @@ +use xsd_parser_types::xml::Base64String; pub type DirectoryReq = DirectoryReqType; #[derive(Debug)] pub struct DirectoryReqType { @@ -29,7 +30,7 @@ pub struct SignedInfoType { #[derive(Debug)] pub struct SignatureValueType { pub id: Option, - pub content: String, + pub content: Base64String, } #[derive(Debug)] pub struct KeyInfoType { @@ -68,7 +69,7 @@ pub struct ReferenceType { pub type_: Option, pub transforms: Option, pub digest_method: DigestMethodType, - pub digest_value: String, + pub digest_value: Base64String, } #[derive(Debug)] pub struct KeyValueType { @@ -108,7 +109,7 @@ pub struct SpkiDataType { } #[derive(Debug)] pub struct SpkiDataTypeContent { - pub spki_sexp: String, + pub spki_sexp: Base64String, } #[derive(Debug)] pub struct TransformsType { @@ -121,15 +122,15 @@ pub struct DigestMethodType { #[derive(Debug)] pub struct DsaKeyValueType { pub content_36: Option, - pub g: Option, - pub y: String, - pub j: Option, + pub g: Option, + pub y: Base64String, + pub j: Option, pub content_37: Option, } #[derive(Debug)] pub struct RsaKeyValueType { - pub modulus: String, - pub exponent: String, + pub modulus: Base64String, + pub exponent: Base64String, } #[derive(Debug)] pub struct X509DataContent19Type { @@ -138,19 +139,19 @@ pub struct X509DataContent19Type { #[derive(Debug)] pub enum X509DataContent19TypeContent { X509IssuerSerial(X509IssuerSerialType), - X509Ski(String), + X509Ski(Base64String), X509SubjectName(String), - X509Certificate(String), - X509Crl(String), + X509Certificate(Base64String), + X509Crl(Base64String), } #[derive(Debug)] pub struct PgpDataContent23Type { - pub pgp_key_id: String, - pub pgp_key_packet: Option, + pub pgp_key_id: Base64String, + pub pgp_key_packet: Option, } #[derive(Debug)] pub struct PgpDataContent25Type { - pub pgp_key_packet: String, + pub pgp_key_packet: Base64String, } #[derive(Debug)] pub struct TransformType { @@ -163,13 +164,13 @@ pub enum TransformTypeContent { } #[derive(Debug)] pub struct DsaKeyValueContent36Type { - pub p: String, - pub q: String, + pub p: Base64String, + pub q: Base64String, } #[derive(Debug)] pub struct DsaKeyValueContent37Type { - pub seed: String, - pub pgen_counter: String, + pub seed: Base64String, + pub pgen_counter: Base64String, } #[derive(Debug)] pub struct X509IssuerSerialType { diff --git a/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/quick_xml.rs b/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/quick_xml.rs index b9b66848..20d0978f 100644 --- a/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/quick_xml.rs +++ b/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/quick_xml.rs @@ -1,6 +1,7 @@ use xsd_parser_types::{ misc::{Namespace, NamespacePrefix}, quick_xml::{Error, WithDeserializer, WithSerializer}, + xml::Base64String, }; pub const NS_XS: Namespace = Namespace::new_const(b"http://www.w3.org/2001/XMLSchema"); pub const NS_XML: Namespace = Namespace::new_const(b"http://www.w3.org/XML/1998/namespace"); @@ -115,7 +116,7 @@ impl WithDeserializer for SignedInfoType { #[derive(Debug)] pub struct SignatureValueType { pub id: Option, - pub content: String, + pub content: Base64String, } impl WithSerializer for SignatureValueType { type Serializer<'x> = quick_xml_serialize::SignatureValueTypeSerializer<'x>; @@ -262,7 +263,7 @@ pub struct ReferenceType { pub type_: Option, pub transforms: Option, pub digest_method: DigestMethodType, - pub digest_value: String, + pub digest_value: Base64String, } impl WithSerializer for ReferenceType { type Serializer<'x> = quick_xml_serialize::ReferenceTypeSerializer<'x>; @@ -446,7 +447,7 @@ pub struct SpkiDataType { } #[derive(Debug)] pub struct SpkiDataTypeContent { - pub spki_sexp: String, + pub spki_sexp: Base64String, } impl WithSerializer for SpkiDataType { type Serializer<'x> = quick_xml_serialize::SpkiDataTypeSerializer<'x>; @@ -531,9 +532,9 @@ impl WithDeserializer for DigestMethodType { #[derive(Debug)] pub struct DsaKeyValueType { pub content_36: Option, - pub g: Option, - pub y: String, - pub j: Option, + pub g: Option, + pub y: Base64String, + pub j: Option, pub content_37: Option, } impl WithSerializer for DsaKeyValueType { @@ -556,8 +557,8 @@ impl WithDeserializer for DsaKeyValueType { } #[derive(Debug)] pub struct RsaKeyValueType { - pub modulus: String, - pub exponent: String, + pub modulus: Base64String, + pub exponent: Base64String, } impl WithSerializer for RsaKeyValueType { type Serializer<'x> = quick_xml_serialize::RsaKeyValueTypeSerializer<'x>; @@ -584,10 +585,10 @@ pub struct X509DataContent19Type { #[derive(Debug)] pub enum X509DataContent19TypeContent { X509IssuerSerial(X509IssuerSerialType), - X509Ski(String), + X509Ski(Base64String), X509SubjectName(String), - X509Certificate(String), - X509Crl(String), + X509Certificate(Base64String), + X509Crl(Base64String), } impl WithSerializer for X509DataContent19Type { type Serializer<'x> = quick_xml_serialize::X509DataContent19TypeSerializer<'x>; @@ -631,8 +632,8 @@ impl WithDeserializer for X509DataContent19TypeContent { } #[derive(Debug)] pub struct PgpDataContent23Type { - pub pgp_key_id: String, - pub pgp_key_packet: Option, + pub pgp_key_id: Base64String, + pub pgp_key_packet: Option, } impl WithSerializer for PgpDataContent23Type { type Serializer<'x> = quick_xml_serialize::PgpDataContent23TypeSerializer<'x>; @@ -654,7 +655,7 @@ impl WithDeserializer for PgpDataContent23Type { } #[derive(Debug)] pub struct PgpDataContent25Type { - pub pgp_key_packet: String, + pub pgp_key_packet: Base64String, } impl WithSerializer for PgpDataContent25Type { type Serializer<'x> = quick_xml_serialize::PgpDataContent25TypeSerializer<'x>; @@ -721,8 +722,8 @@ impl WithDeserializer for TransformTypeContent { } #[derive(Debug)] pub struct DsaKeyValueContent36Type { - pub p: String, - pub q: String, + pub p: Base64String, + pub q: Base64String, } impl WithSerializer for DsaKeyValueContent36Type { type Serializer<'x> = quick_xml_serialize::DsaKeyValueContent36TypeSerializer<'x>; @@ -744,8 +745,8 @@ impl WithDeserializer for DsaKeyValueContent36Type { } #[derive(Debug)] pub struct DsaKeyValueContent37Type { - pub seed: String, - pub pgen_counter: String, + pub seed: Base64String, + pub pgen_counter: Base64String, } impl WithSerializer for DsaKeyValueContent37Type { type Serializer<'x> = quick_xml_serialize::DsaKeyValueContent37TypeSerializer<'x>; @@ -790,10 +791,13 @@ impl WithDeserializer for X509IssuerSerialType { } pub mod quick_xml_deserialize { use core::mem::replace; - use xsd_parser_types::quick_xml::{ - BytesStart, ContentDeserializer, DeserializeHelper, Deserializer, DeserializerArtifact, - DeserializerEvent, DeserializerOutput, DeserializerResult, ElementHandlerOutput, Error, - ErrorKind, Event, RawByteStr, WithDeserializer, + use xsd_parser_types::{ + quick_xml::{ + BytesStart, ContentDeserializer, DeserializeHelper, Deserializer, DeserializerArtifact, + DeserializerEvent, DeserializerOutput, DeserializerResult, ElementHandlerOutput, Error, + ErrorKind, Event, RawByteStr, WithDeserializer, + }, + xml::Base64String, }; #[derive(Debug)] pub struct DirectoryReqTypeDeserializer { @@ -2221,13 +2225,13 @@ pub mod quick_xml_deserialize { #[derive(Debug)] pub struct SignatureValueTypeDeserializer { id: Option, - content: Option, + content: Option, state__: Box, } #[derive(Debug)] enum SignatureValueTypeDeserializerState { Init__, - Content__(::Deserializer), + Content__(::Deserializer), Unknown__, } impl SignatureValueTypeDeserializer { @@ -2263,7 +2267,7 @@ pub mod quick_xml_deserialize { } Ok(()) } - fn store_content(&mut self, value: String) -> Result<(), Error> { + fn store_content(&mut self, value: Base64String) -> Result<(), Error> { if self.content.is_some() { Err(ErrorKind::DuplicateContent)?; } @@ -2273,7 +2277,7 @@ pub mod quick_xml_deserialize { fn handle_content<'de>( mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, ) -> DeserializerResult<'de, super::SignatureValueType> { use SignatureValueTypeDeserializerState as S; let DeserializerOutput { @@ -3652,7 +3656,7 @@ pub mod quick_xml_deserialize { type_: Option, transforms: Option, digest_method: Option, - digest_value: Option, + digest_value: Option, state__: Box, } #[derive(Debug)] @@ -3660,7 +3664,7 @@ pub mod quick_xml_deserialize { Init__, Transforms(Option<::Deserializer>), DigestMethod(Option<::Deserializer>), - DigestValue(Option<::Deserializer>), + DigestValue(Option<::Deserializer>), Done__, Unknown__, } @@ -3741,7 +3745,7 @@ pub mod quick_xml_deserialize { self.digest_method = Some(value); Ok(()) } - fn store_digest_value(&mut self, value: String) -> Result<(), Error> { + fn store_digest_value(&mut self, value: Base64String) -> Result<(), Error> { if self.digest_value.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"DigestValue", @@ -3823,7 +3827,7 @@ pub mod quick_xml_deserialize { fn handle_digest_value<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use ReferenceTypeDeserializerState as S; @@ -5559,13 +5563,13 @@ pub mod quick_xml_deserialize { } #[derive(Debug)] pub struct SpkiDataTypeContentDeserializer { - spki_sexp: Option, + spki_sexp: Option, state__: Box, } #[derive(Debug)] enum SpkiDataTypeContentDeserializerState { Init__, - SpkiSexp(Option<::Deserializer>), + SpkiSexp(Option<::Deserializer>), Done__, Unknown__, } @@ -5584,7 +5588,7 @@ pub mod quick_xml_deserialize { } Ok(()) } - fn store_spki_sexp(&mut self, value: String) -> Result<(), Error> { + fn store_spki_sexp(&mut self, value: Base64String) -> Result<(), Error> { if self.spki_sexp.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"SPKISexp", @@ -5596,7 +5600,7 @@ pub mod quick_xml_deserialize { fn handle_spki_sexp<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use SpkiDataTypeContentDeserializerState as S; @@ -6018,9 +6022,9 @@ pub mod quick_xml_deserialize { #[derive(Debug)] pub struct DsaKeyValueTypeDeserializer { content_36: Option, - g: Option, - y: Option, - j: Option, + g: Option, + y: Option, + j: Option, content_37: Option, state__: Box, } @@ -6028,9 +6032,9 @@ pub mod quick_xml_deserialize { enum DsaKeyValueTypeDeserializerState { Init__, Content36(Option<::Deserializer>), - G(Option<::Deserializer>), - Y(Option<::Deserializer>), - J(Option<::Deserializer>), + G(Option<::Deserializer>), + Y(Option<::Deserializer>), + J(Option<::Deserializer>), Content37(Option<::Deserializer>), Done__, Unknown__, @@ -6085,21 +6089,21 @@ pub mod quick_xml_deserialize { self.content_36 = Some(value); Ok(()) } - fn store_g(&mut self, value: String) -> Result<(), Error> { + fn store_g(&mut self, value: Base64String) -> Result<(), Error> { if self.g.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice(b"G")))?; } self.g = Some(value); Ok(()) } - fn store_y(&mut self, value: String) -> Result<(), Error> { + fn store_y(&mut self, value: Base64String) -> Result<(), Error> { if self.y.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice(b"Y")))?; } self.y = Some(value); Ok(()) } - fn store_j(&mut self, value: String) -> Result<(), Error> { + fn store_j(&mut self, value: Base64String) -> Result<(), Error> { if self.j.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice(b"J")))?; } @@ -6154,7 +6158,7 @@ pub mod quick_xml_deserialize { fn handle_g<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use DsaKeyValueTypeDeserializerState as S; @@ -6187,7 +6191,7 @@ pub mod quick_xml_deserialize { fn handle_y<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use DsaKeyValueTypeDeserializerState as S; @@ -6224,7 +6228,7 @@ pub mod quick_xml_deserialize { fn handle_j<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use DsaKeyValueTypeDeserializerState as S; @@ -6501,15 +6505,15 @@ pub mod quick_xml_deserialize { } #[derive(Debug)] pub struct RsaKeyValueTypeDeserializer { - modulus: Option, - exponent: Option, + modulus: Option, + exponent: Option, state__: Box, } #[derive(Debug)] enum RsaKeyValueTypeDeserializerState { Init__, - Modulus(Option<::Deserializer>), - Exponent(Option<::Deserializer>), + Modulus(Option<::Deserializer>), + Exponent(Option<::Deserializer>), Done__, Unknown__, } @@ -6545,7 +6549,7 @@ pub mod quick_xml_deserialize { } Ok(()) } - fn store_modulus(&mut self, value: String) -> Result<(), Error> { + fn store_modulus(&mut self, value: Base64String) -> Result<(), Error> { if self.modulus.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"Modulus", @@ -6554,7 +6558,7 @@ pub mod quick_xml_deserialize { self.modulus = Some(value); Ok(()) } - fn store_exponent(&mut self, value: String) -> Result<(), Error> { + fn store_exponent(&mut self, value: Base64String) -> Result<(), Error> { if self.exponent.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"Exponent", @@ -6566,7 +6570,7 @@ pub mod quick_xml_deserialize { fn handle_modulus<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use RsaKeyValueTypeDeserializerState as S; @@ -6603,7 +6607,7 @@ pub mod quick_xml_deserialize { fn handle_exponent<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use RsaKeyValueTypeDeserializerState as S; @@ -6939,9 +6943,9 @@ pub mod quick_xml_deserialize { Option<::Deserializer>, ), X509Ski( - Option, - Option<::Deserializer>, - Option<::Deserializer>, + Option, + Option<::Deserializer>, + Option<::Deserializer>, ), X509SubjectName( Option, @@ -6949,14 +6953,14 @@ pub mod quick_xml_deserialize { Option<::Deserializer>, ), X509Certificate( - Option, - Option<::Deserializer>, - Option<::Deserializer>, + Option, + Option<::Deserializer>, + Option<::Deserializer>, ), X509Crl( - Option, - Option<::Deserializer>, - Option<::Deserializer>, + Option, + Option<::Deserializer>, + Option<::Deserializer>, ), Done__(super::X509DataContent19TypeContent), Unknown__, @@ -6985,7 +6989,7 @@ pub mod quick_xml_deserialize { helper.resolve_local_name(x.name(), &super::NS_DS), Some(b"X509SKI") ) { - let output = ::init(helper, event)?; + let output = ::init(helper, event)?; return self.handle_x509_ski(helper, Default::default(), None, output); } if matches!( @@ -6999,14 +7003,14 @@ pub mod quick_xml_deserialize { helper.resolve_local_name(x.name(), &super::NS_DS), Some(b"X509Certificate") ) { - let output = ::init(helper, event)?; + let output = ::init(helper, event)?; return self.handle_x509_certificate(helper, Default::default(), None, output); } if matches!( helper.resolve_local_name(x.name(), &super::NS_DS), Some(b"X509CRL") ) { - let output = ::init(helper, event)?; + let output = ::init(helper, event)?; return self.handle_x509_crl(helper, Default::default(), None, output); } } @@ -7081,7 +7085,10 @@ pub mod quick_xml_deserialize { *values = Some(value); Ok(()) } - fn store_x509_ski(values: &mut Option, value: String) -> Result<(), Error> { + fn store_x509_ski( + values: &mut Option, + value: Base64String, + ) -> Result<(), Error> { if values.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"X509SKI", @@ -7102,7 +7109,10 @@ pub mod quick_xml_deserialize { *values = Some(value); Ok(()) } - fn store_x509_certificate(values: &mut Option, value: String) -> Result<(), Error> { + fn store_x509_certificate( + values: &mut Option, + value: Base64String, + ) -> Result<(), Error> { if values.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"X509Certificate", @@ -7111,7 +7121,10 @@ pub mod quick_xml_deserialize { *values = Some(value); Ok(()) } - fn store_x509_crl(values: &mut Option, value: String) -> Result<(), Error> { + fn store_x509_crl( + values: &mut Option, + value: Base64String, + ) -> Result<(), Error> { if values.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"X509CRL", @@ -7157,9 +7170,9 @@ pub mod quick_xml_deserialize { fn handle_x509_ski<'de>( &mut self, helper: &mut DeserializeHelper, - mut values: Option, - fallback: Option<::Deserializer>, - output: DeserializerOutput<'de, String>, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, Base64String>, ) -> Result, Error> { use X509DataContent19TypeContentDeserializerState as S; let DeserializerOutput { @@ -7225,9 +7238,9 @@ pub mod quick_xml_deserialize { fn handle_x509_certificate<'de>( &mut self, helper: &mut DeserializeHelper, - mut values: Option, - fallback: Option<::Deserializer>, - output: DeserializerOutput<'de, String>, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, Base64String>, ) -> Result, Error> { use X509DataContent19TypeContentDeserializerState as S; let DeserializerOutput { @@ -7259,9 +7272,9 @@ pub mod quick_xml_deserialize { fn handle_x509_crl<'de>( &mut self, helper: &mut DeserializeHelper, - mut values: Option, - fallback: Option<::Deserializer>, - output: DeserializerOutput<'de, String>, + mut values: Option, + fallback: Option<::Deserializer>, + output: DeserializerOutput<'de, Base64String>, ) -> Result, Error> { use X509DataContent19TypeContentDeserializerState as S; let DeserializerOutput { @@ -7501,15 +7514,15 @@ pub mod quick_xml_deserialize { } #[derive(Debug)] pub struct PgpDataContent23TypeDeserializer { - pgp_key_id: Option, - pgp_key_packet: Option, + pgp_key_id: Option, + pgp_key_packet: Option, state__: Box, } #[derive(Debug)] enum PgpDataContent23TypeDeserializerState { Init__, - PgpKeyId(Option<::Deserializer>), - PgpKeyPacket(Option<::Deserializer>), + PgpKeyId(Option<::Deserializer>), + PgpKeyPacket(Option<::Deserializer>), Done__, Unknown__, } @@ -7531,7 +7544,7 @@ pub mod quick_xml_deserialize { } Ok(()) } - fn store_pgp_key_id(&mut self, value: String) -> Result<(), Error> { + fn store_pgp_key_id(&mut self, value: Base64String) -> Result<(), Error> { if self.pgp_key_id.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"PGPKeyID", @@ -7540,7 +7553,7 @@ pub mod quick_xml_deserialize { self.pgp_key_id = Some(value); Ok(()) } - fn store_pgp_key_packet(&mut self, value: String) -> Result<(), Error> { + fn store_pgp_key_packet(&mut self, value: Base64String) -> Result<(), Error> { if self.pgp_key_packet.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"PGPKeyPacket", @@ -7552,7 +7565,7 @@ pub mod quick_xml_deserialize { fn handle_pgp_key_id<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use PgpDataContent23TypeDeserializerState as S; @@ -7589,7 +7602,7 @@ pub mod quick_xml_deserialize { fn handle_pgp_key_packet<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use PgpDataContent23TypeDeserializerState as S; @@ -7764,13 +7777,13 @@ pub mod quick_xml_deserialize { } #[derive(Debug)] pub struct PgpDataContent25TypeDeserializer { - pgp_key_packet: Option, + pgp_key_packet: Option, state__: Box, } #[derive(Debug)] enum PgpDataContent25TypeDeserializerState { Init__, - PgpKeyPacket(Option<::Deserializer>), + PgpKeyPacket(Option<::Deserializer>), Done__, Unknown__, } @@ -7789,7 +7802,7 @@ pub mod quick_xml_deserialize { } Ok(()) } - fn store_pgp_key_packet(&mut self, value: String) -> Result<(), Error> { + fn store_pgp_key_packet(&mut self, value: Base64String) -> Result<(), Error> { if self.pgp_key_packet.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"PGPKeyPacket", @@ -7801,7 +7814,7 @@ pub mod quick_xml_deserialize { fn handle_pgp_key_packet<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use PgpDataContent25TypeDeserializerState as S; @@ -8304,15 +8317,15 @@ pub mod quick_xml_deserialize { } #[derive(Debug)] pub struct DsaKeyValueContent36TypeDeserializer { - p: Option, - q: Option, + p: Option, + q: Option, state__: Box, } #[derive(Debug)] enum DsaKeyValueContent36TypeDeserializerState { Init__, - P(Option<::Deserializer>), - Q(Option<::Deserializer>), + P(Option<::Deserializer>), + Q(Option<::Deserializer>), Done__, Unknown__, } @@ -8330,14 +8343,14 @@ pub mod quick_xml_deserialize { } Ok(()) } - fn store_p(&mut self, value: String) -> Result<(), Error> { + fn store_p(&mut self, value: Base64String) -> Result<(), Error> { if self.p.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice(b"P")))?; } self.p = Some(value); Ok(()) } - fn store_q(&mut self, value: String) -> Result<(), Error> { + fn store_q(&mut self, value: Base64String) -> Result<(), Error> { if self.q.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice(b"Q")))?; } @@ -8347,7 +8360,7 @@ pub mod quick_xml_deserialize { fn handle_p<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use DsaKeyValueContent36TypeDeserializerState as S; @@ -8384,7 +8397,7 @@ pub mod quick_xml_deserialize { fn handle_q<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use DsaKeyValueContent36TypeDeserializerState as S; @@ -8567,15 +8580,15 @@ pub mod quick_xml_deserialize { } #[derive(Debug)] pub struct DsaKeyValueContent37TypeDeserializer { - seed: Option, - pgen_counter: Option, + seed: Option, + pgen_counter: Option, state__: Box, } #[derive(Debug)] enum DsaKeyValueContent37TypeDeserializerState { Init__, - Seed(Option<::Deserializer>), - PgenCounter(Option<::Deserializer>), + Seed(Option<::Deserializer>), + PgenCounter(Option<::Deserializer>), Done__, Unknown__, } @@ -8595,14 +8608,14 @@ pub mod quick_xml_deserialize { } Ok(()) } - fn store_seed(&mut self, value: String) -> Result<(), Error> { + fn store_seed(&mut self, value: Base64String) -> Result<(), Error> { if self.seed.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice(b"Seed")))?; } self.seed = Some(value); Ok(()) } - fn store_pgen_counter(&mut self, value: String) -> Result<(), Error> { + fn store_pgen_counter(&mut self, value: Base64String) -> Result<(), Error> { if self.pgen_counter.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"PgenCounter", @@ -8614,7 +8627,7 @@ pub mod quick_xml_deserialize { fn handle_seed<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use DsaKeyValueContent37TypeDeserializerState as S; @@ -8651,7 +8664,7 @@ pub mod quick_xml_deserialize { fn handle_pgen_counter<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option, ) -> Result, Error> { use DsaKeyValueContent37TypeDeserializerState as S; @@ -9101,9 +9114,12 @@ pub mod quick_xml_deserialize { } } pub mod quick_xml_serialize { - use xsd_parser_types::quick_xml::{ - BytesEnd, BytesStart, Error, Event, IterSerializer, SerializeHelper, Serializer, - WithSerializer, + use xsd_parser_types::{ + quick_xml::{ + BytesEnd, BytesStart, Error, Event, IterSerializer, SerializeHelper, Serializer, + WithSerializer, + }, + xml::Base64String, }; #[derive(Debug)] pub struct DirectoryReqTypeSerializer<'ser> { @@ -9494,7 +9510,7 @@ pub mod quick_xml_serialize { #[derive(Debug)] pub(super) enum SignatureValueTypeSerializerState<'ser> { Init__, - Content__(::Serializer<'ser>), + Content__(::Serializer<'ser>), End__, Done__, Phantom__(&'ser ()), @@ -9915,7 +9931,7 @@ pub mod quick_xml_serialize { IterSerializer<'ser, Option<&'ser super::TransformsType>, super::TransformsType>, ), DigestMethod(::Serializer<'ser>), - DigestValue(::Serializer<'ser>), + DigestValue(::Serializer<'ser>), End__, Done__, Phantom__(&'ser ()), @@ -10508,7 +10524,7 @@ pub mod quick_xml_serialize { #[derive(Debug)] pub(super) enum SpkiDataTypeContentSerializerState<'ser> { Init__, - SpkiSexp(::Serializer<'ser>), + SpkiSexp(::Serializer<'ser>), Done__, Phantom__(&'ser ()), } @@ -10683,9 +10699,9 @@ pub mod quick_xml_serialize { super::DsaKeyValueContent36Type, >, ), - G(IterSerializer<'ser, Option<&'ser String>, String>), - Y(::Serializer<'ser>), - J(IterSerializer<'ser, Option<&'ser String>, String>), + G(IterSerializer<'ser, Option<&'ser Base64String>, Base64String>), + Y(::Serializer<'ser>), + J(IterSerializer<'ser, Option<&'ser Base64String>, Base64String>), Content37( IterSerializer< 'ser, @@ -10796,8 +10812,8 @@ pub mod quick_xml_serialize { #[derive(Debug)] pub(super) enum RsaKeyValueTypeSerializerState<'ser> { Init__, - Modulus(::Serializer<'ser>), - Exponent(::Serializer<'ser>), + Modulus(::Serializer<'ser>), + Exponent(::Serializer<'ser>), End__, Done__, Phantom__(&'ser ()), @@ -10923,10 +10939,10 @@ pub mod quick_xml_serialize { pub(super) enum X509DataContent19TypeContentSerializerState<'ser> { Init__, X509IssuerSerial(::Serializer<'ser>), - X509Ski(::Serializer<'ser>), + X509Ski(::Serializer<'ser>), X509SubjectName(::Serializer<'ser>), - X509Certificate(::Serializer<'ser>), - X509Crl(::Serializer<'ser>), + X509Certificate(::Serializer<'ser>), + X509Crl(::Serializer<'ser>), Done__, Phantom__(&'ser ()), } @@ -11045,8 +11061,8 @@ pub mod quick_xml_serialize { #[derive(Debug)] pub(super) enum PgpDataContent23TypeSerializerState<'ser> { Init__, - PgpKeyId(::Serializer<'ser>), - PgpKeyPacket(IterSerializer<'ser, Option<&'ser String>, String>), + PgpKeyId(::Serializer<'ser>), + PgpKeyPacket(IterSerializer<'ser, Option<&'ser Base64String>, Base64String>), Done__, Phantom__(&'ser ()), } @@ -11112,7 +11128,7 @@ pub mod quick_xml_serialize { #[derive(Debug)] pub(super) enum PgpDataContent25TypeSerializerState<'ser> { Init__, - PgpKeyPacket(::Serializer<'ser>), + PgpKeyPacket(::Serializer<'ser>), Done__, Phantom__(&'ser ()), } @@ -11281,8 +11297,8 @@ pub mod quick_xml_serialize { #[derive(Debug)] pub(super) enum DsaKeyValueContent36TypeSerializerState<'ser> { Init__, - P(::Serializer<'ser>), - Q(::Serializer<'ser>), + P(::Serializer<'ser>), + Q(::Serializer<'ser>), Done__, Phantom__(&'ser ()), } @@ -11340,8 +11356,8 @@ pub mod quick_xml_serialize { #[derive(Debug)] pub(super) enum DsaKeyValueContent37TypeSerializerState<'ser> { Init__, - Seed(::Serializer<'ser>), - PgenCounter(::Serializer<'ser>), + Seed(::Serializer<'ser>), + PgenCounter(::Serializer<'ser>), Done__, Phantom__(&'ser ()), } diff --git a/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/serde_quick_xml.rs b/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/serde_quick_xml.rs index a8fbd197..e51583d1 100644 --- a/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/serde_quick_xml.rs +++ b/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/serde_quick_xml.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use xsd_parser_types::xml::Base64String; pub type DirectoryReq = DirectoryReqType; #[derive(Debug, Deserialize, Serialize)] pub struct DirectoryReqType { @@ -46,8 +47,8 @@ pub struct SignedInfoType { pub struct SignatureValueType { #[serde(default, rename = "@Id")] pub id: Option, - #[serde(default, rename = "$text")] - pub content: String, + #[serde(rename = "$text")] + pub content: Base64String, } #[derive(Debug, Deserialize, Serialize)] pub struct KeyInfoType { @@ -107,7 +108,7 @@ pub struct ReferenceType { #[serde(rename = "DigestMethod")] pub digest_method: DigestMethodType, #[serde(rename = "DigestValue")] - pub digest_value: String, + pub digest_value: Base64String, } #[derive(Debug, Deserialize, Serialize)] pub struct KeyValueType { @@ -140,13 +141,13 @@ pub enum X509DataTypeContent { #[serde(rename = "X509IssuerSerial")] X509IssuerSerial(X509IssuerSerialType), #[serde(rename = "X509SKI")] - X509Ski(String), + X509Ski(Base64String), #[serde(rename = "X509SubjectName")] X509SubjectName(String), #[serde(rename = "X509Certificate")] - X509Certificate(String), + X509Certificate(Base64String), #[serde(rename = "X509CRL")] - X509Crl(String), + X509Crl(Base64String), } #[derive(Debug, Deserialize, Serialize)] pub struct PgpDataType { @@ -156,9 +157,9 @@ pub struct PgpDataType { #[derive(Debug, Deserialize, Serialize)] pub enum PgpDataTypeContent { #[serde(rename = "PGPKeyID")] - PgpKeyId(String), + PgpKeyId(Base64String), #[serde(rename = "PGPKeyPacket")] - PgpKeyPacket(String), + PgpKeyPacket(Base64String), } #[derive(Debug, Deserialize, Serialize)] pub struct SpkiDataType { @@ -168,7 +169,7 @@ pub struct SpkiDataType { #[derive(Debug, Deserialize, Serialize)] pub struct SpkiDataTypeContent { #[serde(rename = "SPKISexp")] - pub spki_sexp: String, + pub spki_sexp: Base64String, } #[derive(Debug, Deserialize, Serialize)] pub struct TransformsType { @@ -183,26 +184,26 @@ pub struct DigestMethodType { #[derive(Debug, Deserialize, Serialize)] pub struct DsaKeyValueType { #[serde(default, rename = "P")] - pub p: Option, + pub p: Option, #[serde(default, rename = "Q")] - pub q: Option, + pub q: Option, #[serde(default, rename = "G")] - pub g: Option, + pub g: Option, #[serde(rename = "Y")] - pub y: String, + pub y: Base64String, #[serde(default, rename = "J")] - pub j: Option, + pub j: Option, #[serde(default, rename = "Seed")] - pub seed: Option, + pub seed: Option, #[serde(default, rename = "PgenCounter")] - pub pgen_counter: Option, + pub pgen_counter: Option, } #[derive(Debug, Deserialize, Serialize)] pub struct RsaKeyValueType { #[serde(rename = "Modulus")] - pub modulus: String, + pub modulus: Base64String, #[serde(rename = "Exponent")] - pub exponent: String, + pub exponent: Base64String, } #[derive(Debug, Deserialize, Serialize)] pub struct X509IssuerSerialType { diff --git a/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/serde_xml_rs_v7.rs b/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/serde_xml_rs_v7.rs index 3c4346ac..6ed8396e 100644 --- a/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/serde_xml_rs_v7.rs +++ b/xsd-parser/tests/schema/ideal_merchant_acquirer/expected/serde_xml_rs_v7.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use xsd_parser_types::xml::Base64String; pub type DirectoryReq = DirectoryReqType; #[derive(Debug, Deserialize, Serialize)] pub struct DirectoryReqType { @@ -46,8 +47,8 @@ pub struct SignedInfoType { pub struct SignatureValueType { #[serde(default, rename = "Id")] pub id: Option, - #[serde(default, rename = "$value")] - pub content: String, + #[serde(rename = "$value")] + pub content: Base64String, } #[derive(Debug, Deserialize, Serialize)] pub struct KeyInfoType { @@ -107,7 +108,7 @@ pub struct ReferenceType { #[serde(rename = "DigestMethod")] pub digest_method: DigestMethodType, #[serde(rename = "DigestValue")] - pub digest_value: String, + pub digest_value: Base64String, } #[derive(Debug, Deserialize, Serialize)] pub struct KeyValueType { @@ -140,13 +141,13 @@ pub enum X509DataTypeContent { #[serde(rename = "X509IssuerSerial")] X509IssuerSerial(X509IssuerSerialType), #[serde(rename = "X509SKI")] - X509Ski(String), + X509Ski(Base64String), #[serde(rename = "X509SubjectName")] X509SubjectName(String), #[serde(rename = "X509Certificate")] - X509Certificate(String), + X509Certificate(Base64String), #[serde(rename = "X509CRL")] - X509Crl(String), + X509Crl(Base64String), } #[derive(Debug, Deserialize, Serialize)] pub struct PgpDataType { @@ -156,9 +157,9 @@ pub struct PgpDataType { #[derive(Debug, Deserialize, Serialize)] pub enum PgpDataTypeContent { #[serde(rename = "PGPKeyID")] - PgpKeyId(String), + PgpKeyId(Base64String), #[serde(rename = "PGPKeyPacket")] - PgpKeyPacket(String), + PgpKeyPacket(Base64String), } #[derive(Debug, Deserialize, Serialize)] pub struct SpkiDataType { @@ -168,7 +169,7 @@ pub struct SpkiDataType { #[derive(Debug, Deserialize, Serialize)] pub struct SpkiDataTypeContent { #[serde(rename = "SPKISexp")] - pub spki_sexp: String, + pub spki_sexp: Base64String, } #[derive(Debug, Deserialize, Serialize)] pub struct TransformsType { @@ -183,26 +184,26 @@ pub struct DigestMethodType { #[derive(Debug, Deserialize, Serialize)] pub struct DsaKeyValueType { #[serde(default, rename = "P")] - pub p: Option, + pub p: Option, #[serde(default, rename = "Q")] - pub q: Option, + pub q: Option, #[serde(default, rename = "G")] - pub g: Option, + pub g: Option, #[serde(rename = "Y")] - pub y: String, + pub y: Base64String, #[serde(default, rename = "J")] - pub j: Option, + pub j: Option, #[serde(default, rename = "Seed")] - pub seed: Option, + pub seed: Option, #[serde(default, rename = "PgenCounter")] - pub pgen_counter: Option, + pub pgen_counter: Option, } #[derive(Debug, Deserialize, Serialize)] pub struct RsaKeyValueType { #[serde(rename = "Modulus")] - pub modulus: String, + pub modulus: Base64String, #[serde(rename = "Exponent")] - pub exponent: String, + pub exponent: Base64String, } #[derive(Debug, Deserialize, Serialize)] pub struct X509IssuerSerialType { diff --git a/xsd-parser/tests/schema/musicxml/expected/default.rs b/xsd-parser/tests/schema/musicxml/expected/default.rs index 0529b6aa..c7b92557 100644 --- a/xsd-parser/tests/schema/musicxml/expected/default.rs +++ b/xsd-parser/tests/schema/musicxml/expected/default.rs @@ -4167,7 +4167,7 @@ pub mod xs { pub content: ::std::string::String, } pub type AnyUri = ::std::string::String; - pub type Base64Binary = ::std::string::String; + pub type Base64Binary = ::xsd_parser_types::xml::Base64String; pub type Boolean = ::core::primitive::bool; pub type Byte = ::core::primitive::i8; pub type Date = ::std::string::String; @@ -4181,7 +4181,7 @@ pub mod xs { pub type GMonthDay = ::std::string::String; pub type GYear = ::std::string::String; pub type GYearMonth = ::std::string::String; - pub type HexBinary = ::std::string::String; + pub type HexBinary = ::xsd_parser_types::xml::HexString; pub type Int = ::core::primitive::i32; pub type Integer = ::num::BigInt; pub type Language = ::std::string::String; diff --git a/xsd-parser/tests/schema/musicxml/expected/quick_xml.rs b/xsd-parser/tests/schema/musicxml/expected/quick_xml.rs index adbaae25..101c4268 100644 --- a/xsd-parser/tests/schema/musicxml/expected/quick_xml.rs +++ b/xsd-parser/tests/schema/musicxml/expected/quick_xml.rs @@ -161662,7 +161662,7 @@ pub mod xs { type Deserializer = quick_xml_deserialize::AnySimpleTypeDeserializer; } pub type AnyUri = ::std::string::String; - pub type Base64Binary = ::std::string::String; + pub type Base64Binary = ::xsd_parser_types::xml::Base64String; pub type Boolean = ::core::primitive::bool; pub type Byte = ::core::primitive::i8; pub type Date = ::std::string::String; @@ -161676,7 +161676,7 @@ pub mod xs { pub type GMonthDay = ::std::string::String; pub type GYear = ::std::string::String; pub type GYearMonth = ::std::string::String; - pub type HexBinary = ::std::string::String; + pub type HexBinary = ::xsd_parser_types::xml::HexString; pub type Int = ::core::primitive::i32; pub type Integer = ::num::BigInt; pub type Language = ::std::string::String; diff --git a/xsd-parser/tests/schema/ofd/expected/default.rs b/xsd-parser/tests/schema/ofd/expected/default.rs index 4b6066ff..f35550c4 100644 --- a/xsd-parser/tests/schema/ofd/expected/default.rs +++ b/xsd-parser/tests/schema/ofd/expected/default.rs @@ -1106,6 +1106,7 @@ pub mod res { } } pub mod signature { + use xsd_parser_types::xml::Base64String; pub type Sianature = SianatureXElementType; #[derive(Debug)] pub struct SianatureXElementType { @@ -1151,7 +1152,7 @@ pub mod signature { #[derive(Debug)] pub struct SianatureSiqnedInfoReferencesReferenceXElementType { pub file_ref: String, - pub check_value: String, + pub check_value: Base64String, } } pub mod signatures { @@ -1197,6 +1198,7 @@ pub mod version { pub mod xs { use core::num::{NonZeroIsize, NonZeroUsize}; use num::{BigInt, BigUint}; + use xsd_parser_types::xml::{Base64String, HexString}; #[derive(Debug, Default)] pub struct EntitiesXType(pub Vec); pub type EntityXType = String; @@ -1215,7 +1217,7 @@ pub mod xs { pub content: String, } pub type AnyUriXType = String; - pub type Base64BinaryXType = String; + pub type Base64BinaryXType = Base64String; pub type BooleanXType = bool; pub type ByteXType = i8; pub type DateXType = String; @@ -1229,7 +1231,7 @@ pub mod xs { pub type GMonthDayXType = String; pub type GYearXType = String; pub type GYearMonthXType = String; - pub type HexBinaryXType = String; + pub type HexBinaryXType = HexString; pub type IntXType = i32; pub type IntegerXType = BigInt; pub type LanguageXType = String; diff --git a/xsd-parser/tests/schema/ofd/expected/quick_xml.rs b/xsd-parser/tests/schema/ofd/expected/quick_xml.rs index 38b546a3..5bd933d8 100644 --- a/xsd-parser/tests/schema/ofd/expected/quick_xml.rs +++ b/xsd-parser/tests/schema/ofd/expected/quick_xml.rs @@ -48556,10 +48556,13 @@ pub mod res { } pub mod signature { use std::borrow::Cow; - use xsd_parser_types::quick_xml::{ - DeserializeBytes, DeserializeHelper, Error, ErrorKind, RawByteStr, SerializeBytes, - SerializeHelper, WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, - WithSerializer, + use xsd_parser_types::{ + quick_xml::{ + DeserializeBytes, DeserializeHelper, Error, ErrorKind, RawByteStr, SerializeBytes, + SerializeHelper, WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, + WithSerializer, + }, + xml::Base64String, }; pub type Sianature = SianatureXElementType; #[derive(Debug)] @@ -48735,7 +48738,7 @@ pub mod signature { #[derive(Debug)] pub struct SianatureSiqnedInfoReferencesReferenceXElementType { pub file_ref: String, - pub check_value: String, + pub check_value: Base64String, } impl WithSerializer for SianatureSiqnedInfoReferencesReferenceXElementType { type Serializer<'x> = @@ -48754,10 +48757,13 @@ pub mod signature { } pub mod quick_xml_deserialize { use core::mem::replace; - use xsd_parser_types::quick_xml::{ - BytesStart, DeserializeHelper, Deserializer, DeserializerArtifact, DeserializerEvent, - DeserializerOutput, DeserializerResult, ElementHandlerOutput, Error, ErrorKind, Event, - RawByteStr, WithDeserializer, + use xsd_parser_types::{ + quick_xml::{ + BytesStart, DeserializeHelper, Deserializer, DeserializerArtifact, + DeserializerEvent, DeserializerOutput, DeserializerResult, ElementHandlerOutput, + Error, ErrorKind, Event, RawByteStr, WithDeserializer, + }, + xml::Base64String, }; #[derive(Debug)] pub struct SianatureXElementTypeDeserializer { @@ -50224,13 +50230,13 @@ pub mod signature { #[derive(Debug)] pub struct SianatureSiqnedInfoReferencesReferenceXElementTypeDeserializer { file_ref: String, - check_value: Option, + check_value: Option, state__: Box, } #[derive(Debug)] enum SianatureSiqnedInfoReferencesReferenceXElementTypeDeserializerState { Init__, - CheckValue(Option<::Deserializer>), + CheckValue(Option<::Deserializer>), Done__, Unknown__, } @@ -50274,7 +50280,7 @@ pub mod signature { } Ok(()) } - fn store_check_value(&mut self, value: String) -> Result<(), Error> { + fn store_check_value(&mut self, value: Base64String) -> Result<(), Error> { if self.check_value.is_some() { Err(ErrorKind::DuplicateElement(RawByteStr::from_slice( b"CheckValue", @@ -50286,7 +50292,7 @@ pub mod signature { fn handle_check_value<'de>( &mut self, helper: &mut DeserializeHelper, - output: DeserializerOutput<'de, String>, + output: DeserializerOutput<'de, Base64String>, fallback: &mut Option< SianatureSiqnedInfoReferencesReferenceXElementTypeDeserializerState, >, @@ -50428,9 +50434,12 @@ pub mod signature { } } pub mod quick_xml_serialize { - use xsd_parser_types::quick_xml::{ - BytesEnd, BytesStart, Error, Event, IterSerializer, SerializeHelper, Serializer, - WithSerializer, + use xsd_parser_types::{ + quick_xml::{ + BytesEnd, BytesStart, Error, Event, IterSerializer, SerializeHelper, Serializer, + WithSerializer, + }, + xml::Base64String, }; #[derive(Debug)] pub struct SianatureXElementTypeSerializer<'ser> { @@ -50877,7 +50886,7 @@ pub mod signature { #[derive(Debug)] pub(super) enum SianatureSiqnedInfoReferencesReferenceXElementTypeSerializerState<'ser> { Init__, - CheckValue(::Serializer<'ser>), + CheckValue(::Serializer<'ser>), End__, Done__, Phantom__(&'ser ()), @@ -52493,9 +52502,12 @@ pub mod xs { use core::num::{NonZeroIsize, NonZeroUsize}; use num::{BigInt, BigUint}; use std::borrow::Cow; - use xsd_parser_types::quick_xml::{ - DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, - WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, WithSerializer, + use xsd_parser_types::{ + quick_xml::{ + DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, + WithDeserializer, WithDeserializerFromBytes, WithSerializeToBytes, WithSerializer, + }, + xml::{Base64String, HexString}, }; #[derive(Debug, Default)] pub struct EntitiesXType(pub Vec); @@ -52560,7 +52572,7 @@ pub mod xs { type Deserializer = quick_xml_deserialize::AnySimpleTypeXTypeDeserializer; } pub type AnyUriXType = String; - pub type Base64BinaryXType = String; + pub type Base64BinaryXType = Base64String; pub type BooleanXType = bool; pub type ByteXType = i8; pub type DateXType = String; @@ -52574,7 +52586,7 @@ pub mod xs { pub type GMonthDayXType = String; pub type GYearXType = String; pub type GYearMonthXType = String; - pub type HexBinaryXType = String; + pub type HexBinaryXType = HexString; pub type IntXType = i32; pub type IntegerXType = BigInt; pub type LanguageXType = String; diff --git a/xsd-parser/tests/schema/opendrive/v1_4/expected/default.rs b/xsd-parser/tests/schema/opendrive/v1_4/expected/default.rs index 538f6fa2..794bf602 100644 --- a/xsd-parser/tests/schema/opendrive/v1_4/expected/default.rs +++ b/xsd-parser/tests/schema/opendrive/v1_4/expected/default.rs @@ -1,3 +1,4 @@ +use xsd_parser_types::xml::{Base64String, HexString}; pub type OpenDrive = OpenDriveXElementType; #[derive(Debug)] pub struct OpenDriveXElementType { @@ -291,7 +292,7 @@ pub type AnySimpleTypeXType = String; #[derive(Debug)] pub struct AnyTypeXType; pub type AnyUriXType = String; -pub type Base64BinaryXType = String; +pub type Base64BinaryXType = Base64String; pub type BooleanXType = bool; pub type ByteXType = i8; pub type DateXType = String; @@ -305,7 +306,7 @@ pub type GMonthXType = String; pub type GMonthDayXType = String; pub type GYearXType = String; pub type GYearMonthXType = String; -pub type HexBinaryXType = String; +pub type HexBinaryXType = HexString; pub type IntXType = i32; pub type IntegerXType = i32; pub type LanguageXType = String; diff --git a/xsd-parser/tests/schema/opendrive/v1_6/expected/default.rs b/xsd-parser/tests/schema/opendrive/v1_6/expected/default.rs index 79c30a27..56ea5c5c 100644 --- a/xsd-parser/tests/schema/opendrive/v1_6/expected/default.rs +++ b/xsd-parser/tests/schema/opendrive/v1_6/expected/default.rs @@ -1,3 +1,4 @@ +use xsd_parser_types::xml::{Base64String, HexString}; pub type OpenDrive = OpenDriveXElementType; #[derive(Debug)] pub struct OpenDriveXElementType { @@ -1180,7 +1181,7 @@ pub type AnySimpleTypeXType = String; #[derive(Debug)] pub struct AnyTypeXType; pub type AnyUriXType = String; -pub type Base64BinaryXType = String; +pub type Base64BinaryXType = Base64String; pub type BooleanXType = bool; pub type ByteXType = i8; pub type DateXType = String; @@ -1194,7 +1195,7 @@ pub type GMonthXType = String; pub type GMonthDayXType = String; pub type GYearXType = String; pub type GYearMonthXType = String; -pub type HexBinaryXType = String; +pub type HexBinaryXType = HexString; pub type IntXType = i32; pub type IntegerXType = i32; pub type LanguageXType = String; diff --git a/xsd-parser/tests/schema/xml_catalogs/expected/default.rs b/xsd-parser/tests/schema/xml_catalogs/expected/default.rs index cdf35d59..46883ad7 100644 --- a/xsd-parser/tests/schema/xml_catalogs/expected/default.rs +++ b/xsd-parser/tests/schema/xml_catalogs/expected/default.rs @@ -128,6 +128,7 @@ pub mod er { pub type UriSuffix = UriSuffixType; } pub mod xs { + use xsd_parser_types::xml::{Base64String, HexString}; #[derive(Debug, Default)] pub struct EntitiesType(pub Vec); pub type EntityType = String; @@ -142,7 +143,7 @@ pub mod xs { pub type QNameType = String; pub type AnySimpleType = String; pub type AnyUriType = String; - pub type Base64BinaryType = String; + pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -156,7 +157,7 @@ pub mod xs { pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; - pub type HexBinaryType = String; + pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/schema/xml_catalogs/expected/quick_xml.rs b/xsd-parser/tests/schema/xml_catalogs/expected/quick_xml.rs index cc0dc0a3..450bfa2f 100644 --- a/xsd-parser/tests/schema/xml_catalogs/expected/quick_xml.rs +++ b/xsd-parser/tests/schema/xml_catalogs/expected/quick_xml.rs @@ -5391,9 +5391,12 @@ pub mod er { } pub mod xs { use std::borrow::Cow; - use xsd_parser_types::quick_xml::{ - DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, - WithDeserializerFromBytes, WithSerializeToBytes, + use xsd_parser_types::{ + quick_xml::{ + DeserializeBytes, DeserializeHelper, Error, SerializeBytes, SerializeHelper, + WithDeserializerFromBytes, WithSerializeToBytes, + }, + xml::{Base64String, HexString}, }; #[derive(Debug, Default)] pub struct EntitiesType(pub Vec); @@ -5436,7 +5439,7 @@ pub mod xs { pub type QNameType = String; pub type AnySimpleType = String; pub type AnyUriType = String; - pub type Base64BinaryType = String; + pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -5450,7 +5453,7 @@ pub mod xs { pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; - pub type HexBinaryType = String; + pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/schema/xml_catalogs/expected/serde_quick_xml.rs b/xsd-parser/tests/schema/xml_catalogs/expected/serde_quick_xml.rs index 8d8edfd9..061b9aaf 100644 --- a/xsd-parser/tests/schema/xml_catalogs/expected/serde_quick_xml.rs +++ b/xsd-parser/tests/schema/xml_catalogs/expected/serde_quick_xml.rs @@ -193,6 +193,7 @@ pub mod er { } pub mod xs { use serde::{Deserialize, Serialize}; + use xsd_parser_types::xml::{Base64String, HexString}; #[derive(Debug, Default, Deserialize, Serialize)] pub struct EntitiesType(pub Vec); pub type EntityType = String; @@ -207,7 +208,7 @@ pub mod xs { pub type QNameType = String; pub type AnySimpleType = String; pub type AnyUriType = String; - pub type Base64BinaryType = String; + pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -221,7 +222,7 @@ pub mod xs { pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; - pub type HexBinaryType = String; + pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String; diff --git a/xsd-parser/tests/schema/xml_catalogs/expected/serde_xml_rs.rs b/xsd-parser/tests/schema/xml_catalogs/expected/serde_xml_rs.rs index 5ed043d3..7085f411 100644 --- a/xsd-parser/tests/schema/xml_catalogs/expected/serde_xml_rs.rs +++ b/xsd-parser/tests/schema/xml_catalogs/expected/serde_xml_rs.rs @@ -220,6 +220,7 @@ pub mod er { } pub mod xs { use serde::{Deserialize, Serialize}; + use xsd_parser_types::xml::{Base64String, HexString}; #[derive(Debug, Default, Deserialize, Serialize)] pub struct EntitiesType(pub Vec); pub type EntityType = String; @@ -234,7 +235,7 @@ pub mod xs { pub type QNameType = String; pub type AnySimpleType = String; pub type AnyUriType = String; - pub type Base64BinaryType = String; + pub type Base64BinaryType = Base64String; pub type BooleanType = bool; pub type ByteType = i8; pub type DateType = String; @@ -248,7 +249,7 @@ pub mod xs { pub type GMonthDayType = String; pub type GYearType = String; pub type GYearMonthType = String; - pub type HexBinaryType = String; + pub type HexBinaryType = HexString; pub type IntType = i32; pub type IntegerType = i32; pub type LanguageType = String;