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

#[serde(flatten)] doesn't work with #[serde(default)] for externally tagged enums #1626

Open
slckl opened this issue Sep 9, 2019 · 6 comments · May be fixed by #2687
Open

#[serde(flatten)] doesn't work with #[serde(default)] for externally tagged enums #1626

slckl opened this issue Sep 9, 2019 · 6 comments · May be fixed by #2687
Labels

Comments

@slckl
Copy link

slckl commented Sep 9, 2019

Given this:

#[derive(Deserialize, Debug)]
enum SomeEnum {
    A(u32),
    B(u32),
}

impl Default for SomeEnum {
    fn default() -> Self {
        SomeEnum::B(1)
    }
}

#[derive(Deserialize, Debug)]
struct SomeStruct {
    filler: u32,
    #[serde(default)]
    #[serde(flatten)]
    some_enum: SomeEnum,
}

trying to deserialize this yaml:

filler: 1

into SomeStruct panics with a message:

no variant of enum SomeEnum found in flattened data

I hoped it would pick up the default value specified for SomeEnum instead...

Playground example.

Is this a bug or is this not supported?
Docs don't cover this, I tried searching issues, but couldn't find anything quite like this.

@dtolnay dtolnay added the derive label Sep 9, 2019
@dtolnay
Copy link
Member

dtolnay commented Sep 9, 2019

Thanks, I would accept a PR to make this work.

@slckl
Copy link
Author

slckl commented Sep 9, 2019

Happy to give it a try, but I haven't dug too much into Serde's internals. Any pointers on where to start?

@Ploppz
Copy link

Ploppz commented Sep 13, 2019

I need the same behaviour, but with internal tagging. My example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3dcd2fca7a231d6c1d7d41ff830e8d2e
Edit: never mind, I realize my problem can easily be solved by using external tagging and renaming the ty field to type.

@heftig
Copy link
Contributor

heftig commented Mar 27, 2020

FTR, the issue isn't restricted to external tagging; other forms of tagging don't make it work, either.

@veeg
Copy link

veeg commented May 20, 2021

I encounter the same issue when using #[serde(other)] for the externally tagged enum, e.g.,:

#[derive(Deserialize, Debug)]
enum SomeEnum {
    A(u32),
    B(u32),
    #[serde(other)]
    C,
}

#[derive(Deserialize, Debug)]
struct SomeStruct {
    filler: u32,
    #[serde(flatten)]
    some_enum: SomeEnum,
}

My use-case specifically is to still be able to deserialize a collection of SomeStruct after the sender may have added another SomeEnum variant. I am interested in the SomeStructs existence, and shared metadata, without necessarily knowing all variants and details of SomeEnum that exist.

@gamife

This comment was marked as off-topic.

mfw78 pushed a commit to cowprotocol/services that referenced this issue Dec 25, 2023
# Description
We've been seeing error message alerts when loading very competition
data from the db. This is expected (cf. #2143) however it is pertubating
on-call. The alternative would be to downgrade the warning to an error,
however I feel we may be losing signal of future breakages in this case.

# Changes
<!-- List of detailed changes (how the change is accomplished) -->

- [x] use serde[(default)] where possible
- [x] for score, which is a flattened enum that doesn't support defaults
(cf. this [open issue](serde-rs/serde#1626)),
we go back to making it an optional. This is fine since with
rank-by-surplus we likely no longer need mandatory score anymore
anyways.

## How to test
Unit test for old transactions data
flavio added a commit to flavio/kube that referenced this issue Jan 25, 2024
…tion

The `serde` crate has a bug that prevents the proper deserialization of
attributes that are using the `flatten` and `default` directives.
See [1] and [2].

This bug affects the freshly introduced `ObjectList.types` attribute.
It's not possible to deserialize an `ObjectList` that is missing the
`apiVersion` and/or the `kind` values.

This commit introduces a custom deserializer for the `types` attribute
of `ObjectList`.

On top of handling the deserialization case, the custom deserializer
provides better default values compared to the ones of the stock
`TypeMeta`.
The `TypeMeta` struct has empty strings as default values. However, in the
context of `ObjectList`, proper default values should be `v1` and `List`
instead.

[1] serde-rs/serde#1626
[2] serde-rs/serde#1879

Signed-off-by: Flavio Castelli <[email protected]>
clux pushed a commit to kube-rs/kube that referenced this issue Jan 26, 2024
* fix: ObjectList handle missing apiVersion and kind during deserialization

The `serde` crate has a bug that prevents the proper deserialization of
attributes that are using the `flatten` and `default` directives.
See [1] and [2].

This bug affects the freshly introduced `ObjectList.types` attribute.
It's not possible to deserialize an `ObjectList` that is missing the
`apiVersion` and/or the `kind` values.

This commit introduces a custom deserializer for the `types` attribute
of `ObjectList`.

On top of handling the deserialization case, the custom deserializer
provides better default values compared to the ones of the stock
`TypeMeta`.
The `TypeMeta` struct has empty strings as default values. However, in the
context of `ObjectList`, proper default values should be `v1` and `List`
instead.

[1] serde-rs/serde#1626
[2] serde-rs/serde#1879

Signed-off-by: Flavio Castelli <[email protected]>

* ObjectList: derive the `Clone` trait

Ensure `ObjectList` derive the `Clone` trait.

Signed-off-by: Flavio Castelli <[email protected]>

* chore: fix rustfmt warning

Signed-off-by: Flavio Castelli <[email protected]>

---------

Signed-off-by: Flavio Castelli <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

6 participants