Function serde_kicad_sexpr::deserialize_option
source · [−]pub fn deserialize_option<'de, D, T>(
deserializer: D
) -> Result<Option<T>, D::Error> where
D: Deserializer<'de>,
T: Deserialize<'de>,
Expand description
Deserialize an Option
in a way that is supported by the s-expression format.
Example
#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields, rename = "size")]
struct Size(f32, f32);
#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields, rename = "thickness")]
struct Thickness(f32);
#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields, rename = "font")]
struct Font {
size: Size,
// This attribute enables our custom deserialize logic.
#[serde(deserialize_with = "serde_kicad_sexpr::deserialize_option")]
thickness: Option<Thickness>,
bold: bool
}
Description
The s-expression format is not only not self-describing, but also does not provide any way
to see if a value is “missing” (i.e. None
) without knowing its type. Unfortunately, serde
expects us to decide if the value is present before we know its type: In the above example,
we have the input string "bold)"
and need to know if thickness
is present or not, without
knowing that thickness
is an s-expr and not, say, an enum that has a variant called bold
.
This custom deserialize logic therefore avoids calling Deserializer::deserialize_option
alltogether. Instead, we’ll try to deserialize the value as if it was present, and return
None
if the deserializer returns an error before calling the visitor. This is likely
indicative of a type error, that would indicate a missing value.
Drawbacks
Using this deserialize logic might hide errors in the input. If this optional value is the last value that gets deserialized, and the deserialization failed due to some error other than a type error, it might get hidden.
Also, if trying to deserialize the value alters the state of the deserializer, it could lead to incorrect deserialization.