What I mean by that is the following:
Given this struct:
struct SomeObj {
someProp: bool
}
Is there a way to force Serde to assign true / false to someProp
when its value is NOT boolean in the JSON input?
Normally, serde would just return an error in such cases (invalid type, expected XY..etc). But would it be possible to suppress the error and just provide some meaningful default value instead?
I know this is possible doing something like:
#[serde(from = "serde_json::Value")]
struct SomeObj {
someProp: bool
}
impl From<serde_json::Value> for SomeObj {
...
}
But there there are a huge number of complex and large structs I need to deal with, so handling this globally would be much easier.
You can always override serde
's choice of deserializer with the attribute deserialize_with
. This attribute accepts a function that will be used to deserialize, in place of the usual Deserialize
trait.
#[derive(Serialize, Deserialize)]
struct SomeObj {
#[serde(deserialize_with = "deserialize_bool_or_false")]
someProp: bool
}
fn deserialize_bool_or_false<'de, D>(deserializer: D) -> Result<bool, D::Error>
where D: Deserializer<'de> {
let deserialized = bool::deserialize(deserializer);
// deserialized is a Result<bool, ...>. You can handle the error
// case however you like. This example simply returns false.
Ok(deserialized.unwrap_or(false))
}
You just need to attach that deserialize_with
attribute to every field that you want the custom defaulting behavior on.
If you're willing to pull in an extra dependency, the serde_with
library has DefaultOnError
, which returns the Default::default()
value for a type (that's false
, ""
, 0
, 0.0
, etc.) if any deserialization error occurs on that field. So with that structure, you can mark any field as #[serde_as(deserialize_as = "DefaultOnError")]
and, provided the underlying type implements the trait Default
, it'll just work.
#[serde_as]
#[derive(Serialize, Deserialize)]
struct SomeObj {
#[serde_as(deserialize_as = "DefaultOnError")]
someProp: bool
}
This will work on bool
, any signed or unsigned integer type, floating-point types, strings, and anything that satisfies Default
.