Expand description

Makes a distinction between a missing, unset, or existing value

Some serialization formats make a distinction between missing fields, fields with a null value, and existing values. One such format is JSON. By default it is not easily possible to differentiate between a missing value and a field which is null, as they deserialize to the same value. This helper changes it, by using an Option<Option<T>> to deserialize into.

  • None: Represents a missing value.
  • Some(None): Represents a null value.
  • Some(Some(value)): Represents an existing value.

Examples

#[derive(Deserialize, Serialize)]
struct Doc {
    #[serde(
        default,                                    // <- important for deserialization
        skip_serializing_if = "Option::is_none",    // <- important for serialization
        with = "::serde_with::rust::double_option",
    )]
    a: Option<Option<u8>>,
}
// Missing Value
let s = r#"{}"#;
assert_eq!(Doc { a: None }, serde_json::from_str(s).unwrap());
assert_eq!(s, serde_json::to_string(&Doc { a: None }).unwrap());

// Unset Value
let s = r#"{"a":null}"#;
assert_eq!(Doc { a: Some(None) }, serde_json::from_str(s).unwrap());
assert_eq!(s, serde_json::to_string(&Doc { a: Some(None) }).unwrap());

// Existing Value
let s = r#"{"a":5}"#;
assert_eq!(Doc { a: Some(Some(5)) }, serde_json::from_str(s).unwrap());
assert_eq!(s, serde_json::to_string(&Doc { a: Some(Some(5)) }).unwrap());

Functions

Deserialize potentially non-existing optional value

Serialize optional value