Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a default case for impl_deserialize_for_internally_tagged_enum #634

Merged

Conversation

aesteve
Copy link
Contributor

@aesteve aesteve commented Aug 16, 2023

Attempt to implement #629 .

  • I did not find any unit tests apart from the doctest, let me know if I missed something
  • I tried to make the implementation backwards compatible with the existing one. If I understood correctly, it accepted a , at the end of the list of all variants so I replicated this behaviour. But I think in the current version, it'd accept 2 commas, not sure if what I wrote is the cleanest.
  • I'd really encourage anyone to actually check this (backwards-compatibility especially) in very details, since that's the very first macro I'm writing
  • let me know if the doc is unclear or if you want me to change anything, no problem

@codecov-commenter
Copy link

codecov-commenter commented Aug 16, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 61.24%. Comparing base (5d76174) to head (421dc0f).
Report is 1 commits behind head on master.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #634   +/-   ##
=======================================
  Coverage   61.24%   61.24%           
=======================================
  Files          39       39           
  Lines       16277    16277           
=======================================
  Hits         9969     9969           
  Misses       6308     6308           
Flag Coverage Δ
unittests 61.24% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Collaborator

@Mingun Mingun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, but small improvements are possible. Also, please update Changelog.md: add new entry under Features (links to issues are listed at the end of version section). Link it to the issue #629, not to this PR.

src/serde_helpers.rs Outdated Show resolved Hide resolved
src/serde_helpers.rs Outdated Show resolved Hide resolved
src/serde_helpers.rs Outdated Show resolved Hide resolved
Comment on lines 241 to 242
$( _ => Ok(deserialize_variant!( de, $enum, $($default_variant)+ )), )?
#[allow(unreachable)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use intermediate macro with two possible variants to select required behavior. General idea:

macro_rules! def {
  // variant 1
  (
    $($variant_tag:literal),*
    _ => Ok( $tokens:tt )
  ) => {
    _ => Ok($tokens),
  },
  // variant 2
  (
    $($variant_tag:literal),*
  ) => {
    _ => Err(A::Error::unknown_field(&tag, &[$($variant_tag),+])),
  },
}

// use 
def!(
  $($variant_tag),*
  $( _ => Ok(deserialize_variant!( de, $enum, $($default_variant)? )), )?
)

If $(...)? part exists, then the first alternative would be selected, otherwise the second. That way we would not need to use #[allow(unreachable)] attribute, which could be forbidden in the project via #[forbid(unreachable)]

Copy link
Contributor Author

@aesteve aesteve Aug 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the pointer, I had the conviction the allow_unreachable wasn't a clean solution.

I get the general idea here, but this code doesn't compile ("no rules expected the token ,") and I have no clue what I should change.

Thanks.

Closest I got:

#[macro_export]
#[doc(hidden)]
macro_rules! def {
  // variant 1
  (
    $($variant_tag:literal),*
    _ => Ok($($tokens:tt)*)
  ) => {
    _ => Ok($($tokens)*),
  };
  // variant 2
  (
    $($variant_tag:literal),*
  ) => {
    _ => Err(A::Error::unknown_field(&tag, &[$($variant_tag),+])),
  }
}
match tag.as_ref() {
  $(
    $variant_tag => Ok(deserialize_variant!( de, $enum, $($variant)+ )),
  )*
  quick_xml::def!(
    $($variant_tag),*
    $( _ => Ok(deserialize_variant!( de, $enum, $($default_variant)? )), )?
  )
}

@Mingun Mingun added enhancement serde Issues related to mapping from Rust types to XML labels Oct 6, 2023
@Mingun Mingun force-pushed the default-case-for-internally-tagged-enum-macro branch from b5ad621 to 421dc0f Compare April 29, 2024 15:31
@Mingun Mingun merged commit 9c366bf into tafia:master Apr 29, 2024
6 checks passed
@Mingun
Copy link
Collaborator

Mingun commented Apr 29, 2024

Thanks for your work! I implemented the helper macro myself and push it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement serde Issues related to mapping from Rust types to XML
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants