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

RFC: Support deserializing enum values in internally/untagged enums #2692

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Stebalien
Copy link

This patch adds support for deserializing enum values in internally/untagged enums. E.g.:

#[derive(Debug, Deserialize, PartialEq)]
pub enum Inner {
    A, B, C
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(tag = "type")]
pub enum Internally {
    Variant { inner: Inner },
}

At the moment, if the Deserializer knows that Inner is an enum and calls visit_enum (e.g., a self-describing format that understands enums), this error will be triggered:

Err(de::Error::custom(
"untagged and internally tagged enums do not support enum input",
))

I'm working around this issue by serializing the variant as a Content and visiting the value with EnumAccess::newtype_variant::<Content>.

There is no perfect solution here as the enum value could be a map, tuple, unit, etc. However, given that we're trying to deserialize arbitrary values, deserializing as a "newtype" actually makes a lot of sense:

  1. Deserializers can opt-in to this fairly easily by implementing EnumAccess::newtype_variant_seed.
  2. Types (implementing Deserialize) should "just work" as expected because maps, tuples, etc. are preserved.

If you're interested in this change, I can add some tests. Unfortunately, the token test logic never calls visit_enum from deserialize_any, so testing will either require implementing a custom Deserializer and/or modifying the token deserializer.

Specifically, this deserializes the "variant" as a `Content` and visits
the value with `newtype_variant::<Content>`.

There is no perfect solution here as the enum value could be a map,
tuple, unit, etc. However, given that we're trying to deserialize
arbitrary values, deserializing as a "newtype" actually makes a lot of
sense:

1. Deserializers can opt-in to this fairly easily by implementing
   `EnumAccess::newtype_variant_seed`.
2. Types (implementing `Deserialize`) should "just work" as expected
   because maps, tuples, etc. are preserved.
@Stebalien Stebalien changed the title Support deserializing enum values in internally/untagged enums RFC: Support deserializing enum values in internally/untagged enums Feb 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant