pub fn invalid_option<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
Expand description
A custom Serde deserializer for possibly invalid Option<T>
fields.
When deserializing CSV data, it is sometimes desirable to simply ignore fields with invalid data. For example, there might be a field that is usually a number, but will occasionally contain garbage data that causes number parsing to fail.
You might be inclined to use, say, Option<i32>
for fields such at this.
By default, however, Option<i32>
will either capture empty fields with
None
or valid numeric fields with Some(the_number)
. If the field is
non-empty and not a valid number, then deserialization will return an error
instead of using None
.
This function allows you to override this default behavior. Namely, if
Option<T>
is deserialized with non-empty but invalid data, then the value
will be None
and the error will be ignored.
ยงExample
This example shows how to parse CSV records with numerical data, even if
some numerical data is absent or invalid. Without the
serde(deserialize_with = "...")
annotations, this example would return
an error.
use std::error::Error;
#[derive(Debug, serde::Deserialize, Eq, PartialEq)]
struct Row {
#[serde(deserialize_with = "csv::invalid_option")]
a: Option<i32>,
#[serde(deserialize_with = "csv::invalid_option")]
b: Option<i32>,
#[serde(deserialize_with = "csv::invalid_option")]
c: Option<i32>,
}
fn example() -> Result<(), Box<dyn Error>> {
let data = "\
a,b,c
5,\"\",xyz
";
let mut rdr = csv::Reader::from_reader(data.as_bytes());
if let Some(result) = rdr.deserialize().next() {
let record: Row = result?;
assert_eq!(record, Row { a: Some(5), b: None, c: None });
Ok(())
} else {
Err(From::from("expected at least one record but got none"))
}
}