diff --git a/rslib/src/notetype/schema11.rs b/rslib/src/notetype/schema11.rs index 5a4238eb5..79f29a1f2 100644 --- a/rslib/src/notetype/schema11.rs +++ b/rslib/src/notetype/schema11.rs @@ -264,7 +264,7 @@ pub struct CardTemplateSchema11 { pub(crate) bqfmt: String, #[serde(default)] pub(crate) bafmt: String, - #[serde(deserialize_with = "default_on_invalid")] + #[serde(deserialize_with = "default_on_invalid", default)] pub(crate) did: Option, #[serde(default, deserialize_with = "default_on_invalid")] pub(crate) bfont: String, diff --git a/rslib/src/serde.rs b/rslib/src/serde.rs index 4b202a17f..6f61627ee 100644 --- a/rslib/src/serde.rs +++ b/rslib/src/serde.rs @@ -8,6 +8,8 @@ pub(crate) use serde_aux::field_attributes::{ }; use serde_json::Value; +/// Note: if you wish to cover the case where a field is missing, make sure you also +/// use the `serde(default)` flag. pub(crate) fn default_on_invalid<'de, T, D>(deserializer: D) -> Result where T: Default + DeTrait<'de>, @@ -63,3 +65,31 @@ impl FromI64 for TimestampSecs { TimestampSecs(val as i64) } } + +#[cfg(test)] +mod test { + use super::*; + use serde::Deserialize; + + #[derive(Deserialize, Debug, PartialEq)] + struct MaybeInvalid { + #[serde(deserialize_with = "default_on_invalid", default)] + field: Option, + } + + #[test] + fn invalid_or_missing() { + assert_eq!( + serde_json::from_str::(r#"{"field": 5}"#).unwrap(), + MaybeInvalid { field: Some(5) } + ); + assert_eq!( + serde_json::from_str::(r#"{"field": "5"}"#).unwrap(), + MaybeInvalid { field: None } + ); + assert_eq!( + serde_json::from_str::(r#"{"another": 5}"#).unwrap(), + MaybeInvalid { field: None } + ); + } +}