Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserialize true/false from 1/0 #1344

Closed
dtolnay opened this issue Aug 3, 2018 · 2 comments
Closed

Deserialize true/false from 1/0 #1344

dtolnay opened this issue Aug 3, 2018 · 2 comments
Labels

Comments

@dtolnay
Copy link
Member

dtolnay commented Aug 3, 2018

Question from IRC:

<Tachyon_> 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 ?

@dtolnay
Copy link
Member Author

dtolnay commented Aug 3, 2018

#[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

@dtolnay dtolnay added the support label Aug 3, 2018
@dtolnay dtolnay closed this as completed Aug 3, 2018
@0xpr03
Copy link

0xpr03 commented Aug 26, 2018

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",
        )),
    }
}

andrey-yantsen added a commit to andrey-yantsen/plex-api.rs that referenced this issue Feb 4, 2022
It was used only for one function. I've replaced it with a tiny example
provided by @dtolnay in
serde-rs/serde#1344 (comment).
@serde-rs serde-rs locked and limited conversation to collaborators Feb 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

No branches or pull requests

2 participants