From c673450812bf207c716598c6fc112ada85fdcca7 Mon Sep 17 00:00:00 2001 From: Lukas Friman Date: Fri, 25 Jul 2025 22:45:44 +0200 Subject: [PATCH 1/2] fix(value): Fixed `deserialize_seq` on most value types. --- xmlity-quick-xml/tests/features.rs | 1 + xmlity-quick-xml/tests/value/mod.rs | 1 + .../tests/value/xbrl_linkbase_ref.rs | 449 ++++++++++++++++++ xmlity/src/types/common.rs | 50 ++ xmlity/src/value/deserializer.rs | 59 +-- 5 files changed, 507 insertions(+), 53 deletions(-) create mode 100644 xmlity-quick-xml/tests/value/mod.rs create mode 100644 xmlity-quick-xml/tests/value/xbrl_linkbase_ref.rs 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/mod.rs b/xmlity-quick-xml/tests/value/mod.rs new file mode 100644 index 0000000..ffd76de --- /dev/null +++ b/xmlity-quick-xml/tests/value/mod.rs @@ -0,0 +1 @@ +pub mod xbrl_linkbase_ref; diff --git a/xmlity-quick-xml/tests/value/xbrl_linkbase_ref.rs b/xmlity-quick-xml/tests/value/xbrl_linkbase_ref.rs new file mode 100644 index 0000000..dc6ea90 --- /dev/null +++ b/xmlity-quick-xml/tests/value/xbrl_linkbase_ref.rs @@ -0,0 +1,449 @@ +pub mod w3_attributes { + pub mod actuate_items { + #[derive(Debug, Clone, Copy, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq)] + #[xvalue(with = actuate_with)] + pub enum Actuate { + OnLoad, + OnRequest, + Other, + None, + } + pub mod actuate_with { + pub fn deserialize<'de, D>( + deserializer: D, + ) -> ::core::result::Result + where + D: ::xmlity::Deserializer<'de>, + { + let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; + let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; + super::Actuate::try_from(value).map_err(::xmlity::de::Error::custom) + } + pub fn serialize( + value: &super::Actuate, + serializer: S, + ) -> ::core::result::Result + where + S: ::xmlity::Serializer, + { + let value: String = Clone::clone(value).into(); + ::xmlity::Serialize::serialize( + String::as_str(&ToString::to_string(&value)), + serializer, + ) + } + } + #[derive(Debug)] + pub enum ActuateParseError { + NonExistent { value: String }, + } + impl ::core::fmt::Display for ActuateParseError { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + match self { + ActuateParseError::NonExistent { value } => { + write!(f, "Value '{:?}' does not exist in the enumeration", value) + } + } + } + } + impl ::core::convert::TryFrom for Actuate { + type Error = ActuateParseError; + fn try_from(value: String) -> ::core::result::Result { + match String::as_str(&value) { + "onLoad" => Ok(Actuate::OnLoad), + "onRequest" => Ok(Actuate::OnRequest), + "other" => Ok(Actuate::Other), + "none" => Ok(Actuate::None), + _ => Err(ActuateParseError::NonExistent { value }), + } + } + } + impl ::core::convert::From for String { + fn from(value: Actuate) -> Self { + match value { + Actuate::OnLoad => String::from("onLoad"), + Actuate::OnRequest => String::from("onRequest"), + Actuate::Other => String::from("other"), + Actuate::None => String::from("none"), + } + } + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "actuate", namespace = "http://www.w3.org/1999/xlink")] + pub struct Actuate(pub actuate_items::Actuate); + impl ::core::convert::From for Actuate { + fn from(value: actuate_items::Actuate) -> Self { + Actuate(value) + } + } + pub mod arcrole_items { + impl ::core::convert::From for Arcrole { + fn from(value: String) -> Self { + Arcrole(value) + } + } + #[derive(Debug, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq, Clone)] + #[xvalue(with = arcrole_with)] + pub struct Arcrole(pub String); + pub mod arcrole_with { + pub fn deserialize<'de, D>( + deserializer: D, + ) -> ::core::result::Result + where + D: ::xmlity::Deserializer<'de>, + { + let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; + let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; + super::Arcrole::try_from(value).map_err(::xmlity::de::Error::custom) + } + pub fn serialize( + value: &super::Arcrole, + serializer: S, + ) -> ::core::result::Result + where + S: ::xmlity::Serializer, + { + let value: String = Clone::clone(value).into(); + ::xmlity::Serialize::serialize( + String::as_str(&ToString::to_string(&value)), + serializer, + ) + } + } + #[derive(Debug, PartialEq, Clone)] + pub enum ArcroleParseError {} + impl ::core::convert::From for String { + fn from(value: Arcrole) -> Self { + value.0 + } + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "arcrole", namespace = "http://www.w3.org/1999/xlink")] + pub struct Arcrole(pub arcrole_items::Arcrole); + impl ::core::convert::From for Arcrole { + fn from(value: arcrole_items::Arcrole) -> Self { + Arcrole(value) + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "from", namespace = "http://www.w3.org/1999/xlink")] + pub struct From(pub String); + impl ::core::convert::From for From { + fn from(value: String) -> Self { + From(value) + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "href", namespace = "http://www.w3.org/1999/xlink")] + pub struct Href(pub String); + impl ::core::convert::From for Href { + fn from(value: String) -> Self { + Href(value) + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "label", namespace = "http://www.w3.org/1999/xlink")] + pub struct Label(pub String); + impl ::core::convert::From for Label { + fn from(value: String) -> Self { + Label(value) + } + } + pub mod role_items { + impl ::core::convert::From for Role { + fn from(value: String) -> Self { + Role(value) + } + } + #[derive(Debug, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq, Clone)] + #[xvalue(with = role_with)] + pub struct Role(pub String); + pub mod role_with { + pub fn deserialize<'de, D>( + deserializer: D, + ) -> ::core::result::Result + where + D: ::xmlity::Deserializer<'de>, + { + let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; + let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; + super::Role::try_from(value).map_err(::xmlity::de::Error::custom) + } + pub fn serialize( + value: &super::Role, + serializer: S, + ) -> ::core::result::Result + where + S: ::xmlity::Serializer, + { + let value: String = Clone::clone(value).into(); + ::xmlity::Serialize::serialize( + String::as_str(&ToString::to_string(&value)), + serializer, + ) + } + } + #[derive(Debug, PartialEq, Clone)] + pub enum RoleParseError {} + impl ::core::convert::From for String { + fn from(value: Role) -> Self { + value.0 + } + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "role", namespace = "http://www.w3.org/1999/xlink")] + pub struct Role(pub role_items::Role); + impl ::core::convert::From for Role { + fn from(value: role_items::Role) -> Self { + Role(value) + } + } + pub mod show_items { + #[derive(Debug, Clone, Copy, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq)] + #[xvalue(with = show_with)] + pub enum Show { + New, + Replace, + Embed, + Other, + None, + } + pub mod show_with { + pub fn deserialize<'de, D>( + deserializer: D, + ) -> ::core::result::Result + where + D: ::xmlity::Deserializer<'de>, + { + let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; + let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; + super::Show::try_from(value).map_err(::xmlity::de::Error::custom) + } + pub fn serialize( + value: &super::Show, + serializer: S, + ) -> ::core::result::Result + where + S: ::xmlity::Serializer, + { + let value: String = Clone::clone(value).into(); + ::xmlity::Serialize::serialize( + String::as_str(&ToString::to_string(&value)), + serializer, + ) + } + } + #[derive(Debug)] + pub enum ShowParseError { + NonExistent { value: String }, + } + impl ::core::fmt::Display for ShowParseError { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + match self { + ShowParseError::NonExistent { value } => { + write!(f, "Value '{:?}' does not exist in the enumeration", value) + } + } + } + } + impl ::core::convert::TryFrom for Show { + type Error = ShowParseError; + fn try_from(value: String) -> ::core::result::Result { + match String::as_str(&value) { + "new" => Ok(Show::New), + "replace" => Ok(Show::Replace), + "embed" => Ok(Show::Embed), + "other" => Ok(Show::Other), + "none" => Ok(Show::None), + _ => Err(ShowParseError::NonExistent { value }), + } + } + } + impl ::core::convert::From for String { + fn from(value: Show) -> Self { + match value { + Show::New => String::from("new"), + Show::Replace => String::from("replace"), + Show::Embed => String::from("embed"), + Show::Other => String::from("other"), + Show::None => String::from("none"), + } + } + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "show", namespace = "http://www.w3.org/1999/xlink")] + pub struct Show(pub show_items::Show); + impl ::core::convert::From for Show { + fn from(value: show_items::Show) -> Self { + Show(value) + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "title", namespace = "http://www.w3.org/1999/xlink")] + pub struct Title(pub String); + impl ::core::convert::From for Title { + fn from(value: String) -> Self { + Title(value) + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "to", namespace = "http://www.w3.org/1999/xlink")] + pub struct To(pub String); + impl ::core::convert::From for To { + fn from(value: String) -> Self { + To(value) + } + } + pub mod type_items { + #[derive(Debug, Clone, Copy, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq)] + #[xvalue(with = type_with)] + pub enum Type { + Simple, + Extended, + Locator, + Arc, + Resource, + Title, + } + pub mod type_with { + pub fn deserialize<'de, D>( + deserializer: D, + ) -> ::core::result::Result + where + D: ::xmlity::Deserializer<'de>, + { + let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; + let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; + super::Type::try_from(value).map_err(::xmlity::de::Error::custom) + } + pub fn serialize( + value: &super::Type, + serializer: S, + ) -> ::core::result::Result + where + S: ::xmlity::Serializer, + { + let value: String = Clone::clone(value).into(); + ::xmlity::Serialize::serialize( + String::as_str(&ToString::to_string(&value)), + serializer, + ) + } + } + #[derive(Debug)] + pub enum TypeParseError { + NonExistent { value: String }, + } + impl ::core::fmt::Display for TypeParseError { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + match self { + TypeParseError::NonExistent { value } => { + write!(f, "Value '{:?}' does not exist in the enumeration", value) + } + } + } + } + impl ::core::convert::TryFrom for Type { + type Error = TypeParseError; + fn try_from(value: String) -> ::core::result::Result { + match String::as_str(&value) { + "simple" => Ok(Type::Simple), + "extended" => Ok(Type::Extended), + "locator" => Ok(Type::Locator), + "arc" => Ok(Type::Arc), + "resource" => Ok(Type::Resource), + "title" => Ok(Type::Title), + _ => Err(TypeParseError::NonExistent { value }), + } + } + } + impl ::core::convert::From for String { + fn from(value: Type) -> Self { + match value { + Type::Simple => String::from("simple"), + Type::Extended => String::from("extended"), + Type::Locator => String::from("locator"), + Type::Arc => String::from("arc"), + Type::Resource => String::from("resource"), + Type::Title => String::from("title"), + } + } + } + } + #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] + #[xattribute(name = "type", namespace = "http://www.w3.org/1999/xlink")] + pub struct Type(pub type_items::Type); + impl ::core::convert::From for Type { + fn from(value: type_items::Type) -> Self { + Type(value) + } + } +} + +pub mod linkbase_ref_items { + #[derive( + Debug, ::xmlity::SerializationGroup, ::xmlity::DeserializationGroup, PartialEq, Clone, + )] + pub struct LinkbaseRef { + #[xattribute(deferred = true)] + pub type_: Box, + #[xattribute(deferred = true)] + pub href: Box, + #[xattribute(deferred = true)] + pub arcrole: Box, + #[xattribute(deferred = true, optional)] + pub role: Option>, + #[xattribute(deferred = true, optional)] + pub title: Option>, + #[xattribute(deferred = true, optional)] + pub show: Option>, + #[xattribute(deferred = true, optional)] + pub actuate: Option>, + } +} +#[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/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) - } -} From 6f5fb4876876c77a054169616e4f18cf94cae759 Mon Sep 17 00:00:00 2001 From: Lukas Friman Date: Fri, 25 Jul 2025 22:48:02 +0200 Subject: [PATCH 2/2] Simplified test. --- .../tests/value/indirect_direct_equal.rs | 34 ++ xmlity-quick-xml/tests/value/mod.rs | 2 +- .../tests/value/xbrl_linkbase_ref.rs | 449 ------------------ 3 files changed, 35 insertions(+), 450 deletions(-) create mode 100644 xmlity-quick-xml/tests/value/indirect_direct_equal.rs delete mode 100644 xmlity-quick-xml/tests/value/xbrl_linkbase_ref.rs 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 index ffd76de..522caa9 100644 --- a/xmlity-quick-xml/tests/value/mod.rs +++ b/xmlity-quick-xml/tests/value/mod.rs @@ -1 +1 @@ -pub mod xbrl_linkbase_ref; +pub mod indirect_direct_equal; diff --git a/xmlity-quick-xml/tests/value/xbrl_linkbase_ref.rs b/xmlity-quick-xml/tests/value/xbrl_linkbase_ref.rs deleted file mode 100644 index dc6ea90..0000000 --- a/xmlity-quick-xml/tests/value/xbrl_linkbase_ref.rs +++ /dev/null @@ -1,449 +0,0 @@ -pub mod w3_attributes { - pub mod actuate_items { - #[derive(Debug, Clone, Copy, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq)] - #[xvalue(with = actuate_with)] - pub enum Actuate { - OnLoad, - OnRequest, - Other, - None, - } - pub mod actuate_with { - pub fn deserialize<'de, D>( - deserializer: D, - ) -> ::core::result::Result - where - D: ::xmlity::Deserializer<'de>, - { - let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; - let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; - super::Actuate::try_from(value).map_err(::xmlity::de::Error::custom) - } - pub fn serialize( - value: &super::Actuate, - serializer: S, - ) -> ::core::result::Result - where - S: ::xmlity::Serializer, - { - let value: String = Clone::clone(value).into(); - ::xmlity::Serialize::serialize( - String::as_str(&ToString::to_string(&value)), - serializer, - ) - } - } - #[derive(Debug)] - pub enum ActuateParseError { - NonExistent { value: String }, - } - impl ::core::fmt::Display for ActuateParseError { - fn fmt( - &self, - f: &mut ::core::fmt::Formatter<'_>, - ) -> ::core::result::Result<(), ::core::fmt::Error> { - match self { - ActuateParseError::NonExistent { value } => { - write!(f, "Value '{:?}' does not exist in the enumeration", value) - } - } - } - } - impl ::core::convert::TryFrom for Actuate { - type Error = ActuateParseError; - fn try_from(value: String) -> ::core::result::Result { - match String::as_str(&value) { - "onLoad" => Ok(Actuate::OnLoad), - "onRequest" => Ok(Actuate::OnRequest), - "other" => Ok(Actuate::Other), - "none" => Ok(Actuate::None), - _ => Err(ActuateParseError::NonExistent { value }), - } - } - } - impl ::core::convert::From for String { - fn from(value: Actuate) -> Self { - match value { - Actuate::OnLoad => String::from("onLoad"), - Actuate::OnRequest => String::from("onRequest"), - Actuate::Other => String::from("other"), - Actuate::None => String::from("none"), - } - } - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "actuate", namespace = "http://www.w3.org/1999/xlink")] - pub struct Actuate(pub actuate_items::Actuate); - impl ::core::convert::From for Actuate { - fn from(value: actuate_items::Actuate) -> Self { - Actuate(value) - } - } - pub mod arcrole_items { - impl ::core::convert::From for Arcrole { - fn from(value: String) -> Self { - Arcrole(value) - } - } - #[derive(Debug, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq, Clone)] - #[xvalue(with = arcrole_with)] - pub struct Arcrole(pub String); - pub mod arcrole_with { - pub fn deserialize<'de, D>( - deserializer: D, - ) -> ::core::result::Result - where - D: ::xmlity::Deserializer<'de>, - { - let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; - let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; - super::Arcrole::try_from(value).map_err(::xmlity::de::Error::custom) - } - pub fn serialize( - value: &super::Arcrole, - serializer: S, - ) -> ::core::result::Result - where - S: ::xmlity::Serializer, - { - let value: String = Clone::clone(value).into(); - ::xmlity::Serialize::serialize( - String::as_str(&ToString::to_string(&value)), - serializer, - ) - } - } - #[derive(Debug, PartialEq, Clone)] - pub enum ArcroleParseError {} - impl ::core::convert::From for String { - fn from(value: Arcrole) -> Self { - value.0 - } - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "arcrole", namespace = "http://www.w3.org/1999/xlink")] - pub struct Arcrole(pub arcrole_items::Arcrole); - impl ::core::convert::From for Arcrole { - fn from(value: arcrole_items::Arcrole) -> Self { - Arcrole(value) - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "from", namespace = "http://www.w3.org/1999/xlink")] - pub struct From(pub String); - impl ::core::convert::From for From { - fn from(value: String) -> Self { - From(value) - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "href", namespace = "http://www.w3.org/1999/xlink")] - pub struct Href(pub String); - impl ::core::convert::From for Href { - fn from(value: String) -> Self { - Href(value) - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "label", namespace = "http://www.w3.org/1999/xlink")] - pub struct Label(pub String); - impl ::core::convert::From for Label { - fn from(value: String) -> Self { - Label(value) - } - } - pub mod role_items { - impl ::core::convert::From for Role { - fn from(value: String) -> Self { - Role(value) - } - } - #[derive(Debug, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq, Clone)] - #[xvalue(with = role_with)] - pub struct Role(pub String); - pub mod role_with { - pub fn deserialize<'de, D>( - deserializer: D, - ) -> ::core::result::Result - where - D: ::xmlity::Deserializer<'de>, - { - let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; - let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; - super::Role::try_from(value).map_err(::xmlity::de::Error::custom) - } - pub fn serialize( - value: &super::Role, - serializer: S, - ) -> ::core::result::Result - where - S: ::xmlity::Serializer, - { - let value: String = Clone::clone(value).into(); - ::xmlity::Serialize::serialize( - String::as_str(&ToString::to_string(&value)), - serializer, - ) - } - } - #[derive(Debug, PartialEq, Clone)] - pub enum RoleParseError {} - impl ::core::convert::From for String { - fn from(value: Role) -> Self { - value.0 - } - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "role", namespace = "http://www.w3.org/1999/xlink")] - pub struct Role(pub role_items::Role); - impl ::core::convert::From for Role { - fn from(value: role_items::Role) -> Self { - Role(value) - } - } - pub mod show_items { - #[derive(Debug, Clone, Copy, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq)] - #[xvalue(with = show_with)] - pub enum Show { - New, - Replace, - Embed, - Other, - None, - } - pub mod show_with { - pub fn deserialize<'de, D>( - deserializer: D, - ) -> ::core::result::Result - where - D: ::xmlity::Deserializer<'de>, - { - let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; - let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; - super::Show::try_from(value).map_err(::xmlity::de::Error::custom) - } - pub fn serialize( - value: &super::Show, - serializer: S, - ) -> ::core::result::Result - where - S: ::xmlity::Serializer, - { - let value: String = Clone::clone(value).into(); - ::xmlity::Serialize::serialize( - String::as_str(&ToString::to_string(&value)), - serializer, - ) - } - } - #[derive(Debug)] - pub enum ShowParseError { - NonExistent { value: String }, - } - impl ::core::fmt::Display for ShowParseError { - fn fmt( - &self, - f: &mut ::core::fmt::Formatter<'_>, - ) -> ::core::result::Result<(), ::core::fmt::Error> { - match self { - ShowParseError::NonExistent { value } => { - write!(f, "Value '{:?}' does not exist in the enumeration", value) - } - } - } - } - impl ::core::convert::TryFrom for Show { - type Error = ShowParseError; - fn try_from(value: String) -> ::core::result::Result { - match String::as_str(&value) { - "new" => Ok(Show::New), - "replace" => Ok(Show::Replace), - "embed" => Ok(Show::Embed), - "other" => Ok(Show::Other), - "none" => Ok(Show::None), - _ => Err(ShowParseError::NonExistent { value }), - } - } - } - impl ::core::convert::From for String { - fn from(value: Show) -> Self { - match value { - Show::New => String::from("new"), - Show::Replace => String::from("replace"), - Show::Embed => String::from("embed"), - Show::Other => String::from("other"), - Show::None => String::from("none"), - } - } - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "show", namespace = "http://www.w3.org/1999/xlink")] - pub struct Show(pub show_items::Show); - impl ::core::convert::From for Show { - fn from(value: show_items::Show) -> Self { - Show(value) - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "title", namespace = "http://www.w3.org/1999/xlink")] - pub struct Title(pub String); - impl ::core::convert::From for Title { - fn from(value: String) -> Self { - Title(value) - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "to", namespace = "http://www.w3.org/1999/xlink")] - pub struct To(pub String); - impl ::core::convert::From for To { - fn from(value: String) -> Self { - To(value) - } - } - pub mod type_items { - #[derive(Debug, Clone, Copy, ::xmlity::Serialize, ::xmlity::Deserialize, PartialEq)] - #[xvalue(with = type_with)] - pub enum Type { - Simple, - Extended, - Locator, - Arc, - Resource, - Title, - } - pub mod type_with { - pub fn deserialize<'de, D>( - deserializer: D, - ) -> ::core::result::Result - where - D: ::xmlity::Deserializer<'de>, - { - let text: String = ::xmlity::Deserialize::deserialize(deserializer)?; - let value: String = text.parse().map_err(::xmlity::de::Error::custom)?; - super::Type::try_from(value).map_err(::xmlity::de::Error::custom) - } - pub fn serialize( - value: &super::Type, - serializer: S, - ) -> ::core::result::Result - where - S: ::xmlity::Serializer, - { - let value: String = Clone::clone(value).into(); - ::xmlity::Serialize::serialize( - String::as_str(&ToString::to_string(&value)), - serializer, - ) - } - } - #[derive(Debug)] - pub enum TypeParseError { - NonExistent { value: String }, - } - impl ::core::fmt::Display for TypeParseError { - fn fmt( - &self, - f: &mut ::core::fmt::Formatter<'_>, - ) -> ::core::result::Result<(), ::core::fmt::Error> { - match self { - TypeParseError::NonExistent { value } => { - write!(f, "Value '{:?}' does not exist in the enumeration", value) - } - } - } - } - impl ::core::convert::TryFrom for Type { - type Error = TypeParseError; - fn try_from(value: String) -> ::core::result::Result { - match String::as_str(&value) { - "simple" => Ok(Type::Simple), - "extended" => Ok(Type::Extended), - "locator" => Ok(Type::Locator), - "arc" => Ok(Type::Arc), - "resource" => Ok(Type::Resource), - "title" => Ok(Type::Title), - _ => Err(TypeParseError::NonExistent { value }), - } - } - } - impl ::core::convert::From for String { - fn from(value: Type) -> Self { - match value { - Type::Simple => String::from("simple"), - Type::Extended => String::from("extended"), - Type::Locator => String::from("locator"), - Type::Arc => String::from("arc"), - Type::Resource => String::from("resource"), - Type::Title => String::from("title"), - } - } - } - } - #[derive(Debug, ::xmlity::SerializeAttribute, ::xmlity::Deserialize, PartialEq, Clone)] - #[xattribute(name = "type", namespace = "http://www.w3.org/1999/xlink")] - pub struct Type(pub type_items::Type); - impl ::core::convert::From for Type { - fn from(value: type_items::Type) -> Self { - Type(value) - } - } -} - -pub mod linkbase_ref_items { - #[derive( - Debug, ::xmlity::SerializationGroup, ::xmlity::DeserializationGroup, PartialEq, Clone, - )] - pub struct LinkbaseRef { - #[xattribute(deferred = true)] - pub type_: Box, - #[xattribute(deferred = true)] - pub href: Box, - #[xattribute(deferred = true)] - pub arcrole: Box, - #[xattribute(deferred = true, optional)] - pub role: Option>, - #[xattribute(deferred = true, optional)] - pub title: Option>, - #[xattribute(deferred = true, optional)] - pub show: Option>, - #[xattribute(deferred = true, optional)] - pub actuate: Option>, - } -} -#[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); -}