Question from IRC:
\
if I have a json where I have a field where true/false is represented as 0/1, can I make serde_json to automagically map it to a bool ?
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
use serde::de::{self, Deserialize, Deserializer, Unexpected};
#[derive(Deserialize, Debug)]
struct Tachyon {
#[serde(deserialize_with = "bool_from_int")]
value: bool,
}
fn bool_from_int<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: Deserializer<'de>,
{
match u8::deserialize(deserializer)? {
0 => Ok(false),
1 => Ok(true),
other => Err(de::Error::invalid_value(
Unexpected::Unsigned(other as u64),
&"zero or one",
)),
}
}
fn main() {
println!("{:?}", serde_json::from_str::<Tachyon>("{\"value\":0}").unwrap());
println!("{:?}", serde_json::from_str::<Tachyon>("{\"value\":1}").unwrap());
println!("{}", serde_json::from_str::<Tachyon>("{\"value\":2}").unwrap_err());
}
Tachyon { value: false }
Tachyon { value: true }
invalid value: integer `2`, expected zero or one at line 1 column 11
Thanks for that example.
In case anyone was wondering how to do the same with strings (with the CSV crate in my case) here my code:
/// example struct
#[derive(Debug,Deserialize)]
struct MyStruct {
#[serde(deserialize_with = "bool_from_string")]
is_ok: bool
}
/// Deserialize bool from String with custom value mapping
fn bool_from_string<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: Deserializer<'de>,
{
match String::deserialize(deserializer)?.as_ref() {
"OK" => Ok(true),
"nOK" => Ok(false),
other => Err(de::Error::invalid_value(
Unexpected::Str(other),
&"OK or nOK",
)),
}
}
Most helpful comment