diff --git a/xmlity-quick-xml/tests/features.rs b/xmlity-quick-xml/tests/features.rs index 69cd023..6e0c9d8 100644 --- a/xmlity-quick-xml/tests/features.rs +++ b/xmlity-quick-xml/tests/features.rs @@ -3,4 +3,5 @@ pub mod groups; pub mod other; pub mod text; pub mod utils; +pub mod value; pub mod with; diff --git a/xmlity-quick-xml/tests/value/indirect_direct_equal.rs b/xmlity-quick-xml/tests/value/indirect_direct_equal.rs new file mode 100644 index 0000000..ad1c470 --- /dev/null +++ b/xmlity-quick-xml/tests/value/indirect_direct_equal.rs @@ -0,0 +1,34 @@ +pub mod linkbase_ref_items { + #[derive( + Debug, ::xmlity::SerializationGroup, ::xmlity::DeserializationGroup, PartialEq, Clone, + )] + pub struct LinkbaseRef {} +} +#[derive(Debug, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq, Clone)] +pub enum LinkbaseRef { + #[xelement( + name = "linkbaseRef", + namespace = "http://www.xbrl.org/2003/linkbase", + allow_unknown_attributes = "any" + )] + LinkbaseRef(#[xgroup] linkbase_ref_items::LinkbaseRef), +} + +const LINKBASE_REF: &str = r###" + +"###; + +#[test] +fn linkbase_ref() { + let direct: LinkbaseRef = + xmlity_quick_xml::from_str(LINKBASE_REF.trim()).expect("Failed to parse linkbaseRef XML"); + + let element: xmlity::value::XmlValue = + xmlity_quick_xml::from_str(LINKBASE_REF.trim()).expect("Failed to parse linkbaseRef XML"); + + let indirect: LinkbaseRef = + xmlity::Deserialize::deserialize(&element).expect("Failed to deserialize linkbaseRef XML"); + + assert_eq!(direct, indirect); +} diff --git a/xmlity-quick-xml/tests/value/mod.rs b/xmlity-quick-xml/tests/value/mod.rs new file mode 100644 index 0000000..522caa9 --- /dev/null +++ b/xmlity-quick-xml/tests/value/mod.rs @@ -0,0 +1 @@ +pub mod indirect_direct_equal; diff --git a/xmlity/src/types/common.rs b/xmlity/src/types/common.rs index f62c94d..ad9636b 100644 --- a/xmlity/src/types/common.rs +++ b/xmlity/src/types/common.rs @@ -159,6 +159,56 @@ impl SerializationGroup for Option { } } +impl<'de, D> de::SeqAccess<'de> for Option<&'de D> +where + &'de D: de::Deserializer<'de>, +{ + type Error = <&'de D as de::Deserializer<'de>>::Error; + + type SubAccess<'g> + = Self + where + Self: 'g; + + fn next_element(&mut self) -> Result, Self::Error> + where + T: Deserialize<'de>, + { + let Some(text) = self.take() else { + return Ok(None); + }; + + match T::deserialize(text) { + Ok(value) => Ok(Some(value)), + Err(_) => { + *self = Some(text); + Ok(None) + } + } + } + + fn next_element_seq(&mut self) -> Result, Self::Error> + where + T: Deserialize<'de>, + { + let Some(text) = self.take() else { + return Ok(None); + }; + + match T::deserialize_seq(text) { + Ok(value) => Ok(Some(value)), + Err(_) => { + *self = Some(text); + Ok(None) + } + } + } + + fn sub_access(&mut self) -> Result, Self::Error> { + Ok(*self) + } +} + impl Serialize for Box { fn serialize(&self, serializer: S) -> Result { (**self).serialize(serializer) diff --git a/xmlity/src/value/deserializer.rs b/xmlity/src/value/deserializer.rs index 1b14fc4..6e744c5 100644 --- a/xmlity/src/value/deserializer.rs +++ b/xmlity/src/value/deserializer.rs @@ -96,7 +96,7 @@ impl<'de> Deserializer<'de> for &'de XmlCData { where V: Visitor<'de>, { - self.deserialize_any(visitor) + visitor.visit_seq(Some(self)) } } @@ -174,7 +174,7 @@ impl<'de> Deserializer<'de> for &'de XmlElement { where V: Visitor<'de>, { - self.deserialize_any(visitor) + visitor.visit_seq(Some(self)) } } @@ -277,7 +277,7 @@ impl<'de> Deserializer<'de> for &'de XmlProcessingInstruction { where V: Visitor<'de>, { - self.deserialize_any(visitor) + visitor.visit_seq(Some(self)) } } @@ -294,7 +294,7 @@ impl<'de> Deserializer<'de> for &'de XmlDecl { where V: Visitor<'de>, { - self.deserialize_any(visitor) + visitor.visit_seq(Some(self)) } } @@ -310,7 +310,7 @@ impl<'de> Deserializer<'de> for &'de XmlComment { where V: Visitor<'de>, { - self.deserialize_any(visitor) + visitor.visit_seq(Some(self)) } } @@ -328,7 +328,7 @@ impl<'de> Deserializer<'de> for &'de XmlDoctype { where V: Visitor<'de>, { - self.deserialize_any(visitor) + visitor.visit_seq(Some(self)) } } @@ -591,50 +591,3 @@ impl<'de> de::XmlText<'de> for &'de XmlText { fn context(&self) -> Self::DeserializeContext<'_> {} } - -impl<'de> de::SeqAccess<'de> for Option<&'de XmlText> { - type Error = XmlValueDeserializerError; - - type SubAccess<'g> - = Self - where - Self: 'g; - - fn next_element(&mut self) -> Result, Self::Error> - where - T: Deserialize<'de>, - { - let Some(text) = self.take() else { - return Ok(None); - }; - - match T::deserialize(text) { - Ok(value) => Ok(Some(value)), - Err(_) => { - *self = Some(text); - Ok(None) - } - } - } - - fn next_element_seq(&mut self) -> Result, Self::Error> - where - T: Deserialize<'de>, - { - let Some(text) = self.take() else { - return Ok(None); - }; - - match T::deserialize_seq(text) { - Ok(value) => Ok(Some(value)), - Err(_) => { - *self = Some(text); - Ok(None) - } - } - } - - fn sub_access(&mut self) -> Result, Self::Error> { - Ok(*self) - } -}