serde-rs / serde

Serialization framework for Rust
https://serde.rs/
Apache License 2.0
8.81k stars 747 forks source link

`Option<T>` defaults to `None` when missing fields #2753

Open emirhantasdeviren opened 1 month ago

emirhantasdeviren commented 1 month ago

Even if #[serde(default)] is not specified on a field with type Option<T> it still falls to None rather returning an error if the field is missing. If this is intentional why does that attribute exist?

Here is the playground link on version 1.0.202 https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7ecdefd0f0b00f70d969571b36a5f50e

valaphee commented 1 month ago

Option<T> is one of the basic buildings block for allowing optional values, when a value is not present its Option<T>::None, therefore doesn't require Default.

#[serde(default)] just maps None to T's Default, which would also be None in the case of Option<T>, and therefore redundant.

And it's easier to write Option<T> instead of:

#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
_: Option<T>
emirhantasdeviren commented 4 weeks ago

Then, I have a question. In the case of a JSON payload how will I know if given field is absent or set as null.

For example in a PATCH endpoint of a resource I need to know if given field is set to null I will update the entity in my database if the field is absent I won't do any change in the database.

In a PUT endpoint I specifically need the field present in the payload even it is Option<T>, it must be set to null or some valid value.

valaphee commented 3 weeks ago

Ah, there is already an issue for this use case https://github.com/serde-rs/serde/issues/1042

atm you would have to create your own type https://stackoverflow.com/questions/44331037/how-can-i-distinguish-between-a-deserialized-field-that-is-missing-and-one-that

valaphee commented 3 weeks ago

Here is a more convenient method https://docs.rs/serde_with/latest/serde_with/rust/double_option/