From c3c81f67967ac413b11783a2186c2e8228160c0c Mon Sep 17 00:00:00 2001 From: Louis Hampton Date: Tue, 30 Jun 2026 00:11:04 +0100 Subject: [PATCH] Allow building xsd-parser-types with xml but without quick-xml --- xsd-parser-types/src/xml/any_simple_type.rs | 5 +++- xsd-parser-types/src/xml/attributes.rs | 17 +++++++++++++ xsd-parser-types/src/xml/mixed.rs | 4 ++- xsd-parser-types/src/xml/mod.rs | 12 ++++++--- xsd-parser-types/src/xml/namespace_scope.rs | 2 ++ xsd-parser-types/src/xml/namespaces.rs | 3 +++ xsd-parser-types/src/xml/qname.rs | 4 +++ xsd-parser-types/src/xml/text.rs | 6 +++++ xsd-parser-types/src/xml/value.rs | 27 +++++++++++++++++++++ 9 files changed, 75 insertions(+), 5 deletions(-) diff --git a/xsd-parser-types/src/xml/any_simple_type.rs b/xsd-parser-types/src/xml/any_simple_type.rs index 9b906747..428890d9 100644 --- a/xsd-parser-types/src/xml/any_simple_type.rs +++ b/xsd-parser-types/src/xml/any_simple_type.rs @@ -10,6 +10,7 @@ use num::{BigInt, BigRational, BigUint}; #[cfg(feature = "quick-xml")] use quick_xml::events::Event; +#[cfg(feature = "quick-xml")] use crate::quick_xml::{DeserializeBytes, SerializeBytes}; use crate::xml::NamespacesShared; @@ -216,6 +217,7 @@ impl WithDeserializer for AnySimpleType { type Deserializer = AnySimpleTypeDeserializer; } +#[cfg(feature = "quick-xml")] impl SerializeBytes for AnySimpleType { fn serialize_bytes(&self, helper: &mut SerializeHelper) -> Result>, Error> { let _helper = helper; @@ -224,6 +226,7 @@ impl SerializeBytes for AnySimpleType { } } +#[cfg(feature = "quick-xml")] impl DeserializeBytes for AnySimpleType { fn deserialize_bytes(helper: &mut DeserializeHelper, bytes: &[u8]) -> Result { Self::deserialize_str(helper, from_utf8(bytes)?) @@ -603,7 +606,7 @@ fn parse_base64_binary(bytes: &str) -> Result { } #[inline] -#[cfg(not(feature = "base64"))] +#[cfg(all(feature = "quick-xml", not(feature = "base64")))] #[allow(clippy::unnecessary_wraps)] fn parse_base64_binary(s: &str) -> Result { Ok(s.to_string().into()) diff --git a/xsd-parser-types/src/xml/attributes.rs b/xsd-parser-types/src/xml/attributes.rs index 7f58421e..dcef403b 100644 --- a/xsd-parser-types/src/xml/attributes.rs +++ b/xsd-parser-types/src/xml/attributes.rs @@ -4,18 +4,33 @@ use std::ops::{Deref, DerefMut}; use encoding_rs::{Encoding, UTF_8}; use indexmap::{map::Entry, IndexMap}; +#[cfg(feature = "quick-xml")] use quick_xml::{ encoding::decode, escape::{resolve_predefined_entity, unescape_with}, events::attributes::Attribute, name::QName, }; +#[cfg(not(feature = "quick-xml"))] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct QName<'a>(pub &'a [u8]); use crate::misc::{format_utf8_slice, RawByteStr}; #[cfg(feature = "quick-xml")] use crate::quick_xml::{Error, ErrorKind}; +#[cfg(not(feature = "quick-xml"))] +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct Attribute<'a> { + /// The key to uniquely define the attribute. + /// + /// If [`Attributes::with_checks`] is turned off, the key might not be unique. + pub key: QName<'a>, + /// The raw value of the attribute. + pub value: Cow<'a, [u8]>, +} + /// Represents a list of unstructured XML attributes. #[derive(Default, Debug, Clone, Eq, PartialEq)] pub struct Attributes<'a>(pub IndexMap, Value<'a>>); @@ -33,6 +48,7 @@ impl<'a> Attributes<'a> { /// /// Raises a [`DuplicateAttribute`](ErrorKind::DuplicateAttribute) error if /// the passed attribute is already part of the list. + #[cfg(feature = "quick-xml")] pub fn push(&mut self, attrib: Attribute<'_>) -> Result<(), Error> { let key = Key(Cow::Owned(attrib.key.0.to_owned())); @@ -154,6 +170,7 @@ impl Borrow<[u8]> for Key<'_> { #[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct Value<'a>(pub Cow<'a, [u8]>); +#[cfg(feature = "quick-xml")] impl Value<'_> { /// Return the unescaped value using UTF-8 encoding. /// diff --git a/xsd-parser-types/src/xml/mixed.rs b/xsd-parser-types/src/xml/mixed.rs index bc616d63..8ac78535 100644 --- a/xsd-parser-types/src/xml/mixed.rs +++ b/xsd-parser-types/src/xml/mixed.rs @@ -11,7 +11,9 @@ use crate::quick_xml::{ WithSerializer, }; -use super::text::{Text, TextDeserializer}; +use super::text::Text; +#[cfg(feature = "quick-xml")] +use super::text::TextDeserializer; /// Used to represent xml elements with mixed content #[derive(Default, Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] diff --git a/xsd-parser-types/src/xml/mod.rs b/xsd-parser-types/src/xml/mod.rs index f2f09c34..11990166 100644 --- a/xsd-parser-types/src/xml/mod.rs +++ b/xsd-parser-types/src/xml/mod.rs @@ -23,14 +23,20 @@ pub use self::attributes::{ AnyAttributes, Attributes, Key as AttributeKey, Value as AttributeValue, }; pub use self::element::{AnyElement, AnyElements, Element, Elements}; -pub use self::mixed::{Mixed, MixedDeserializer, MixedSerializer}; +pub use self::mixed::Mixed; +#[cfg(feature = "quick-xml")] +pub use self::mixed::{MixedDeserializer, MixedSerializer}; pub use self::namespace_scope::NamespaceScope; pub use self::namespaces::{ Key as NamespaceKey, Namespaces, NamespacesShared, Value as NamespaceValue, }; -pub use self::nillable::{Nillable, NillableDeserializer, NillableSerializer}; +pub use self::nillable::Nillable; +#[cfg(feature = "quick-xml")] +pub use self::nillable::{NillableDeserializer, NillableSerializer}; pub use self::qname::QName; -pub use self::text::{Text, TextDeserializer, TextSerializer}; +pub use self::text::Text; +#[cfg(feature = "quick-xml")] +pub use self::text::{TextDeserializer, TextSerializer}; pub use self::value::Value; #[cfg(feature = "quick-xml")] diff --git a/xsd-parser-types/src/xml/namespace_scope.rs b/xsd-parser-types/src/xml/namespace_scope.rs index 1d041815..58637097 100644 --- a/xsd-parser-types/src/xml/namespace_scope.rs +++ b/xsd-parser-types/src/xml/namespace_scope.rs @@ -93,6 +93,7 @@ impl NamespaceScope { } } +#[cfg(feature = "quick-xml")] impl SerializeBytes for NamespaceScope where T: SerializeBytes, @@ -102,6 +103,7 @@ where } } +#[cfg(feature = "quick-xml")] impl DeserializeBytes for NamespaceScope where T: DeserializeBytes, diff --git a/xsd-parser-types/src/xml/namespaces.rs b/xsd-parser-types/src/xml/namespaces.rs index 12678632..0e1b8696 100644 --- a/xsd-parser-types/src/xml/namespaces.rs +++ b/xsd-parser-types/src/xml/namespaces.rs @@ -5,6 +5,7 @@ use std::hash::{Hash, Hasher}; use std::ops::{Deref, DerefMut}; use std::sync::Arc; +#[cfg(feature = "quick-xml")] use quick_xml::name::{Namespace, PrefixDeclaration}; use crate::misc::format_utf8_slice; @@ -76,6 +77,7 @@ where #[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct Key<'a>(pub Cow<'a, [u8]>); +#[cfg(feature = "quick-xml")] impl Key<'_> { /// Get the key value as [`PrefixDeclaration`]. #[must_use] @@ -140,6 +142,7 @@ impl Borrow<[u8]> for Key<'_> { #[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct Value<'a>(pub Cow<'a, [u8]>); +#[cfg(feature = "quick-xml")] impl Value<'_> { /// Get the namespace as [`Namespace`]. #[inline] diff --git a/xsd-parser-types/src/xml/qname.rs b/xsd-parser-types/src/xml/qname.rs index 0e5145c9..1defb8e8 100644 --- a/xsd-parser-types/src/xml/qname.rs +++ b/xsd-parser-types/src/xml/qname.rs @@ -2,9 +2,11 @@ use std::borrow::Cow; use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::hash::{Hash, Hasher}; +#[cfg(feature = "quick-xml")] use quick_xml::name::{QName as QuickXmlQName, ResolveResult}; use crate::misc::{format_utf8_slice, Namespace}; +#[cfg(feature = "quick-xml")] use crate::quick_xml::{WithDeserializerFromBytes, WithSerializeToBytes}; #[cfg(feature = "quick-xml")] @@ -152,6 +154,7 @@ impl SerializeBytes for QName { } } +#[cfg(feature = "quick-xml")] impl WithSerializeToBytes for QName {} #[cfg(feature = "quick-xml")] @@ -161,6 +164,7 @@ impl DeserializeBytes for QName { } } +#[cfg(feature = "quick-xml")] impl WithDeserializerFromBytes for QName {} #[allow(clippy::missing_fields_in_debug)] diff --git a/xsd-parser-types/src/xml/text.rs b/xsd-parser-types/src/xml/text.rs index 49809f89..6a417d9f 100644 --- a/xsd-parser-types/src/xml/text.rs +++ b/xsd-parser-types/src/xml/text.rs @@ -65,6 +65,7 @@ impl DerefMut for Text { } } +#[cfg(feature = "quick-xml")] impl WithSerializer for Text { type Serializer<'x> = TextSerializer<'x>; @@ -80,11 +81,13 @@ impl WithSerializer for Text { } } +#[cfg(feature = "quick-xml")] impl WithDeserializer for Text { type Deserializer = TextDeserializer; } /// Implemented the [`Serializer`](crate::quick_xml::Serializer) trait for [`Text`]. +#[cfg(feature = "quick-xml")] #[derive(Debug)] pub enum TextSerializer<'ser> { /// Emit events for the contained text value. @@ -97,6 +100,7 @@ pub enum TextSerializer<'ser> { Done, } +#[cfg(feature = "quick-xml")] impl<'ser> Serializer<'ser> for TextSerializer<'ser> { fn next(&mut self, helper: &mut SerializeHelper) -> Option, Error>> { let _helper = helper; @@ -111,6 +115,7 @@ impl<'ser> Serializer<'ser> for TextSerializer<'ser> { } /// Implemented the [`Deserializer`] trait for [`Text`]. +#[cfg(feature = "quick-xml")] #[derive(Debug)] pub enum TextDeserializer { /// Init the deserializer @@ -123,6 +128,7 @@ pub enum TextDeserializer { }, } +#[cfg(feature = "quick-xml")] impl<'de> Deserializer<'de, Text> for TextDeserializer { fn init(helper: &mut DeserializeHelper, event: Event<'de>) -> DeserializerResult<'de, Text> { Self::Init.next(helper, event) diff --git a/xsd-parser-types/src/xml/value.rs b/xsd-parser-types/src/xml/value.rs index 2d6e5fca..b0ba2ebb 100644 --- a/xsd-parser-types/src/xml/value.rs +++ b/xsd-parser-types/src/xml/value.rs @@ -1,11 +1,38 @@ use std::fmt::{Debug, Formatter, Result as FmtResult}; +#[cfg(feature = "quick-xml")] use quick_xml::events::{BytesCData, BytesText}; use crate::misc::format_utf8_slice; use super::Element; +#[cfg(not(feature = "quick-xml"))] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct BytesText<'a>(std::borrow::Cow<'a, [u8]>); + +#[cfg(not(feature = "quick-xml"))] +impl<'a> std::ops::Deref for BytesText<'a> { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &self.0 + } +} + +#[cfg(not(feature = "quick-xml"))] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct BytesCData<'a>(std::borrow::Cow<'a, [u8]>); + +#[cfg(not(feature = "quick-xml"))] +impl<'a> std::ops::Deref for BytesCData<'a> { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &self.0 + } +} + /// Represents unstructured XML data. /// /// This is mainly used to store the data contained by an [`Element`].