pub fn deserialize_nested_option<'de, T, D>(
    deserializer: D
) -> Result<Option<Option<T>>, D::Error>where
    T: Deserialize<'de>,
    D: Deserializer<'de>,
Expand description

Deserializes a nested optional field

The outer Option corresponds to the field existence (missing or present). The inner Option corresponds to the field value (unset or value).

You must combine it with the default Serde attribute.

use serde::{Deserialize, Serialize};
use etwin_serde_tools::deserialize_nested_option;

#[derive(Serialize, Deserialize)]
#[derive(Debug, PartialEq, Eq)]
struct User {
  id: u32,
  #[serde(default, deserialize_with = "deserialize_nested_option")]
  username: Option<Option<String>>,
}

assert_eq!(
  serde_json::from_str::<User>(r#"{"id":1}"#).unwrap(),
  User { id: 1, username: None }
);
assert_eq!(
  serde_json::from_str::<User>(r#"{"id":1,"username":null}"#).unwrap(),
  User { id: 1, username: Some(None) }
);
assert_eq!(
  serde_json::from_str::<User>(r#"{"id":1,"username":"demurgos"}"#).unwrap(),
  User { id: 1, username: Some(Some("demurgos".to_string())) }
);