-
-
Notifications
You must be signed in to change notification settings - Fork 788
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
Added #[serde(case_insensitive)] container attribute for case-insensitive identifier deserialization #1902
base: master
Are you sure you want to change the base?
Conversation
Uses eq_ignore_ascii_case() for case-insensitive comparison. Added tests test_case_insensitive_struct, test_case_insensitive_enum, test_case_insensitive_bytes.
Found a small bug, deriving Deserialize on an empty struct with case_insensitive attribute causes the following error:
|
Updated tests. Refactored generated code to use match for case insensitive comparison too.
This doesn't work on flattened structs, need to investigate it further. |
Does this allow enum variants to be case insensitive? Here, I want to be able to deserialize #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum State {
#[serde(rename = "provisioning")]
Provisioning,
#[serde(rename = "deprovisioning")]
Deprovisioning,
#[serde(rename = "succeeded")]
Succeeded,
#[serde(rename = "failed")]
Failed,
#[serde(rename = "networkSourceDeleted")]
NetworkSourceDeleted,
} |
You can mark the whole enum as case insensitive, then all variant names
would be case insensitive. The attribute won't work on a single variant
though.
|
Both the parent struct and the flattened struct must have the case insensitive attribute.
It works now on flattened structs. However, you need to add the #[serde(case_insensitive)] attribute on both the parent struct and the flattened struct. If the attribute is only on the parent struct, the parent struct's fields are case insensitive and the flattened struct's fields case sensitive. If the attribute is not on the parent struct, everything is case sensitive regardless of the flattened struct's attributes. Also, there is quite a lot of duplicate code between Looks like the build also now fails on older Rust versions without the eq_ignore_ascii_case function. Previously the function was used only in the code the derive generated, and the derive already required Rust 1.31 or newer, so it wasn't a problem. Now it's also used in the case insensitive flat map deserializer which is part of the main crate even without derives enabled. Not sure how this should be solved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the build also now fails on older Rust versions without the eq_ignore_ascii_case function. Previously the function was used only in the code the derive generated, and the derive already required Rust 1.31 or newer, so it wasn't a problem. Now it's also used in the case insensitive flat map deserializer which is part of the main crate even without derives enabled.
I landed #1966 to skip compiling the derive helpers on older builds. They should only be needed on 1.31+.
Any progress? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pull request is looking pretty polished to me. I just tested the latest commit 11ee221 in ctaggart/azure-sdk-for-rust#2 and it fixes the deserialization problems with the Azure Storage service. I'd love to see this merged and released.
is this being released? |
@dtolnay, merging this would really help Azure SDK for Rust. What can I do to help this along? |
@dtolnay If docs are holding this back, I can make a PR for documenting this in https://github.com/serde-rs/serde-rs.github.io/blob/master/_src/container-attrs.md |
Looking for comments on #2161 which is an alternative solution that is more generic over the problem |
This PR could help here, unfortunately, seems to be stalling serde-rs/serde#1902
I came here looking for case-insensitive enum deserialization. What's the state of this PR? I don't understand if it's been superseded (and should be closed), or if it's still to be merged (what's keeping it?). Thanks |
Almost 2024 💀 |
It's 2024, will this ever be merged? |
please guys |
Added an attritube that enables case-insensitive container field/variant identifier deserialization.
A similar attribute been requested in #586, which was closed because case-insensitive parsing was provided by the serde-aux crate.
The case insensitive implementation there however seems to first parse the data into a map, convert all keys into lowercase and then deserialize the map into the target type.
This is definitely slower than having the code generated by derive compare the field names using case-insensitive comparison.
The serde_aux implementation also depends on serde_json::Value and might not work for other data formats.
This PR uses eq_ignore_ascii_case() for case-insensitive comparison, which limits it to ASCII characters. This should be sufficient for most use cases, and the standard library currently doesn't have a case insensitive comparsion function that supports any characters.
Also added tests test_case_insensitive_struct, test_case_insensitive_enum and test_case_insensitive_bytes.