macro_rules! impl_deserialize_for_internally_tagged_enum { ( $enum:ty, $tag:literal, $( ($variant_tag:literal => $($variant:tt)+ ) ),* $(,)? ) => { ... }; }
Available on crate feature
serde-types
only.Expand description
A helper to implement Deserialize
for internally tagged enums which
does not use Deserializer::deserialize_any
that produces wrong results
with XML because of serde#1183.
In contrast to deriving Deserialize
this macro assumes that a tag will be
the first element or attribute in the XML.
Example
use quick_xml::de::from_str;
use quick_xml::impl_deserialize_for_internally_tagged_enum;
use serde::Deserialize;
#[derive(Deserialize, Debug, PartialEq)]
struct Root {
one: InternallyTaggedEnum,
two: InternallyTaggedEnum,
three: InternallyTaggedEnum,
}
#[derive(Debug, PartialEq)]
// #[serde(tag = "@tag")]
enum InternallyTaggedEnum {
Unit,
Newtype(Newtype),
Struct {
// #[serde(rename = "@attribute")]
attribute: u32,
element: f32,
},
}
#[derive(Deserialize, Debug, PartialEq)]
struct Newtype {
#[serde(rename = "@attribute")]
attribute: u64,
}
// The macro needs the type of the enum, the tag name,
// and information about all the variants
impl_deserialize_for_internally_tagged_enum!{
InternallyTaggedEnum, "@tag",
("Unit" => Unit),
("Newtype" => Newtype(Newtype)),
("Struct" => Struct {
#[serde(rename = "@attribute")]
attribute: u32,
element: f32,
}),
}
assert_eq!(
from_str::<Root>(r#"
<root>
<one tag="Unit" />
<two tag="Newtype" attribute="42" />
<three tag="Struct" attribute="42">
<element>4.2</element>
</three>
</root>
"#).unwrap(),
Root {
one: InternallyTaggedEnum::Unit,
two: InternallyTaggedEnum::Newtype(Newtype { attribute: 42 }),
three: InternallyTaggedEnum::Struct {
attribute: 42,
element: 4.2,
},
},
);