Question: I currently have a JSON string I am deserializing with `serde_json`.

```
{
  "foo": "<val>" // val can contain "SI" or "NO"
}

```

I would like to deserialize this to a bool using `serde` and a custom lookup that turns "SI" -> true and vice-versa.

```
#[derive(Deserialize)]
pub struct Entry {
   pub foo: bool, // How to express string to bool deserialization ?
}

```

How can I do that simply ?

Answer: 
You could use `deserialize_with` like so:

```rust
#[derive(Deserialize)]
pub struct Entry {
    #[serde(deserialize_with = "deserialize_bool")]
    pub foo: bool,
}

fn deserialize_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
    D: de::Deserializer<'de>,
{
    let s: &str = de::Deserialize::deserialize(deserializer)?;

    match s {
        "SI" => Ok(true),
        "NO" => Ok(false),
        _ => Err(de::Error::unknown_variant(s, &["SI", "NO"])),
    }
}

```

See: <https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0ac9e89f97afc893197d37bc55dba188>
I would use a custom deserializer with ability to convert from different concrete types.

```rust
use serde::{de, Deserialize, Deserializer};
use serde_json::Value;

#[derive(Deserialize)]
pub struct Entry {
  #[serde(deserialize_with = "boolean")]
  pub foo: bool,
}

fn boolean<'de, D: Deserializer<'de>>(deserializer: D) -> Result<bool, D::Error> {
  Ok(match Value::deserialize(deserializer)? {
    Value::Bool(b) => b,
    Value::String(s) => s == "yes",
    Value::Number(num) => num.as_i64().ok_or(de::Error::custom("Invalid number"))? != 0,
    Value::Null => false,
    _ => return Err(de::Error::custom("Wrong type, expected boolean")),
  })
}

```