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_as(as = "Option<OneOrMany<_>>")]#[skip_serializing_none] fails to deserialize with None #311

Closed
apps4uco opened this issue May 2, 2021 · 2 comments

Comments

@apps4uco
Copy link

apps4uco commented May 2, 2021

I have this code which fails. I believe it should be supported.

#[serde_as]
#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Demo {
    #[serde_as(as = "Option<OneOrMany<_>>")]
    contents: Option<Vec<String>>,
}

It serializes fine with a single element in a vector or multiple elements in a vector

It fails with an error when the contents are set to None

failures:

---- tests::vec_none stdout ----
None
Serialized ---
{}

Error: Message("missing field contents", Some(Pos { marker: Marker { index: 4, line: 2, col: 0 }, path: "." }))

Please find a test case attached.

Workaround: Dont specify #[skip_serializing_none]

test.txt

@jonasbb
Copy link
Owner

jonasbb commented May 2, 2021

You need to add #[serde(default)] as an attribute to the contents field too. It is the normal behavior for serde to disable the special treatment regarding missing fields whenever a with annotation is added. The serde_as is equivalent to the with in this regard.

There is an issue to maybe change that in the future #185.

    #[serde_as(as = "Option<OneOrMany<_>>")]
    #[serde(default)]
    contents: Option<Vec<String>>,

I hope that helps.

@apps4uco
Copy link
Author

apps4uco commented May 2, 2021

Great that fixes it. Maybe it could be added as an example to the documentation.

Thanks ever so much

@apps4uco apps4uco closed this as completed May 2, 2021
bors bot added a commit that referenced this issue Jun 6, 2022
470: Simplify `serde_as` handling around `Option`s r=jonasbb a=jonasbb

Using `#[serde_as]` on a field of type `Option` changes the behavior, in that the field can no longer be missing.
This often times was unexpected and lead to confusion (e.g., #183, #185, #311, #417).

Now if both the field and the transformation type are `Option` the `#[serde(default)]` attribute is added. `Option`s are identified by exact text matches and these variants are supported:
* `Option`
* `std::option::Option`, with or without leading `::`
* `core::option::Option`, with or without leading `::`

If a `default` attribute already exists nothing happens. This new behavior can be suppressed by using `#[serde_as(no_default)]` on the field. If the transformation type is not `Option`, e.g., like `NoneAsEmptyString`, nothing happens either.

Closes #185

Co-authored-by: Jonas Bushart <jonas@bushart.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants