簡體   English   中英

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

[英]How do I use Serde to deserialize malformed JSON with True/False?

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

{
  "value": True
}

使用此答案,我嘗試了以下解決方案:

#[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);
}

可在操場上運行

據我所知,問題是輸入未被識別為任何正確的類型,因此沒有任何訪問者 API在這里工作。

更新(2020-02-05)

顯然,這無法用serde_json解決(一種方法是使用自定義數據格式或派生serde_json來添加此功能,因為serde_json不處理無效輸入,請參閱維護者的回答)。

對於其他有類似問題的人,一個hacky 解決方案是將原始響應字符串中的TrueFalse實例替換為truefalse 這絕對不是完美的,因為如果字符串包含TrueFalse ,它們也會被替換,但對於特定用例,這可能是一個可接受的解決方案。

這不是有效的 JSON,因此您不能使用serde_json進行反序列化。

JSON 中的布爾常量是truefalse ,小寫。

一般來說,如果輸入是庫所適用的數據格式,則只能使用特定庫反序列化輸入。

例如,如果您的輸入不是 JSON、CBOR、MessagePack,則不能使用 serde_json、serde_cbor 或 serde_messagepack 對其進行反序列化。

您顯示的輸入似乎是 YAML,因此您可以嘗試 serde_yaml。

fn main() {
    let input = r#" {
                      "value": True
                    } "#;
    println!("{:#?}", serde_yaml::from_str::<serde_yaml::Value>(input).unwrap());
}

換句話說,數據是無效的 JSON 的事實告訴你不要使用哪個庫——serde_json。 為了找到合適的庫它更利於發現一個格式的數據有效的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM