如何使用 Serde 用 True/False 反序列化格式错误的 JSON?

man*_*yel 5 json malformed rust serde

如何使用 Rust 的serde反序列化以下格式错误的 JSON :

{
  "value": True
}
Run Code Online (Sandbox Code Playgroud)

使用此答案,我尝试了以下解决方案:

#[macro_use]
extern crate serde_derive; // 1.0.66
extern crate serde; // 1.0.66
extern crate serde_json; // 1.0.21


use serde::de;
use std::fmt;

#[derive(Debug, PartialEq, Deserialize)]
pub struct Foo {
    #[serde(deserialize_with = "deserialize_capitalized_bool")]
    pub bar: bool,
}

fn deserialize_capitalized_bool<'de, D>(
    deserializer: D,
) -> Result<bool, D::Error>
where
    D: de::Deserializer<'de>,
{
    struct CapitalizedBoolVisitor;

    impl<'de> de::Visitor<'de> for CapitalizedBoolVisitor {
        type Value = bool;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a True or False string")
        }

        fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
        where
            E: de::Error,
        {
            if v == &['T' as u8, 'r' as u8, 'e' as u8] {
                Ok(true)
            } else if v
                == &['F' as u8, 'a' as u8, 'l' as u8, 's' as u8, 'e' as u8]
            {
                Ok(false)
            } else {
                unimplemented!();
            }
        }
    }

    deserializer.deserialize_any(CapitalizedBoolVisitor)
}

fn main() {
    let json = r#"{
        "bar": True
    }"#;

    let foo: Foo = serde_json::from_str(json).unwrap();

    let expected = Foo {
        bar: true
    };
    assert_eq!(foo, expected);
}
Run Code Online (Sandbox Code Playgroud)

可在操场上运行

据我所知,问题是输入未被识别为任何正确的类型,因此没有任何访问者 API在这里工作。

更新(2020-02-05)

显然这是不可能解决的serde_json(一种方法是使用自定义数据格式或分叉serde_json添加此功能,因为serde_json不处理无效输入,请参阅维护者的答案)。

对于遇到类似问题的任何其他人,一个hacky 解决方案是将原始响应字符串中的TrueandFalse实例替换为trueand false。这绝对不是完美的,因为如果字符串包含TrueFalse,它们也会被替换,但对于特定用例,这可能是一个可接受的解决方案。

mca*_*ton 2

这不是有效的 JSON,因此您不能用于serde_json反序列化它。

JSON 中的布尔常量是小写的true和。false