Skip to content

Commit

Permalink
implement tafia#629
Browse files Browse the repository at this point in the history
  • Loading branch information
aesteve committed Aug 16, 2023
1 parent 1be35e1 commit c7f5706
Showing 1 changed file with 59 additions and 1 deletion.
60 changes: 59 additions & 1 deletion src/serde_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,60 @@ macro_rules! deserialize_variant {
/// );
/// ```
///
/// You don't have to provide all the enumeration variants and can use `_` to put every undefined tag into an enumeration variant like so:
/// # Example
///
/// ```
/// # use pretty_assertions::assert_eq;
/// 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)]
/// enum InternallyTaggedEnum {
/// NewType(Newtype),
/// Other,
/// }
///
/// #[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",
/// ("NewType" => NewType(Newtype)),
/// (_ => Other),
/// }
///
/// assert_eq!(
/// from_str::<Root>(r#"
/// <root>
/// <one tag="NewType" attribute="42" />
/// <two tag="Something" ignoredAttribute="something" />
/// <three tag="SomethingElse">
/// <ignoredToo />
/// </three>
/// </root>
/// "#).unwrap(),
/// Root {
/// one: InternallyTaggedEnum::NewType(Newtype { attribute: 42 }),
/// two: InternallyTaggedEnum::Other,
/// three: InternallyTaggedEnum::Other,
/// },
/// );
/// ```
///
/// [internally tagged]: https://serde.rs/enum-representations.html#internally-tagged
/// [serde#1183]: https://github.com/serde-rs/serde/issues/1183
#[macro_export(local_inner_macros)]
Expand All @@ -127,7 +181,9 @@ macro_rules! impl_deserialize_for_internally_tagged_enum {
$tag:literal,
$(
($variant_tag:literal => $($variant:tt)+ )
),* $(,)?
),*
$(, (_ => $($default_variant:tt)+ ))?
$(,)*
) => {
impl<'de> serde::de::Deserialize<'de> for $enum {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
Expand Down Expand Up @@ -182,6 +238,8 @@ macro_rules! impl_deserialize_for_internally_tagged_enum {
$(
$variant_tag => Ok(deserialize_variant!( de, $enum, $($variant)+ )),
)*
$( _ => Ok(deserialize_variant!( de, $enum, $($default_variant)+ )), )?
#[allow(unreachable)]
_ => Err(A::Error::unknown_field(&tag, &[$($variant_tag),+])),
}
}
Expand Down

0 comments on commit c7f5706

Please sign in to comment.