serde icon indicating copy to clipboard operation
serde copied to clipboard

`Option` fields require explicit `default` attribute if `with` attribute specified

Open MaxOhn opened this issue 11 months ago • 1 comments

Usually, the default attribute is not required on Option fields and if such a field is missing it'll just be set as None. If the with attribute is used, however, the default attribute also needs to be specified or the deserialization will fail if the field is missing.

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=875ca8186b694b73047655afd75895e6

Expanding the code highlights the differences

  • Neither with nor default attributes: (missing_field does not error for Option)
let __field0 = match __field0 {
    _serde::__private::Some(__field0) => __field0,
    _serde::__private::None => _serde::__private::de::missing_field("field")?,
};
  • with attribute but no default:
let __field0 = match __field0 {
    _serde::__private::Some(__field0) => __field0,
    _serde::__private::None =>
        return _serde::__private::Err(
            <__A::Error as _serde::de::Error>::missing_field("field")
        ),
};
  • Both with and default attributes:
let __field0 = match __field0 {
    _serde::__private::Some(__field0) => __field0,
    _serde::__private::None => _serde::__private::Default::default(),
};

Just like with, deserialize_with also causes this. serialize_with seems to not have any effect though.

I imagine a simple fix would be to use the same private missing_field function rather than <A::Error>::missing_field.

MaxOhn avatar Jan 05 '25 21:01 MaxOhn

There is some more discussion in https://github.com/serde-rs/serde/issues/723

(related Stack Overflow question/answer, https://stackoverflow.com/questions/44301748/how-can-i-deserialize-an-optional-field-with-custom-functions-using-serde/44303505#44303505)

MadLittleMods avatar Feb 06 '25 22:02 MadLittleMods