使用不规则内容反序列化JSON

时间:2014-08-24 12:23:26

标签: json rust

我有下面的例子,其中2个“不寻常”的事情可能发生:

  • 如果状态为NOK,则data元素将不会包含在内
  • list内部元素的某些属性可能会丢失(在下面的示例中,key2的第二个元素中缺少list

有没有办法使用自动派生对不规则的JSON字符串进行反序列化? 哪个是在Rust中处理这种不规则JSON的最简单/更好的方法?我可以避免编写一个非常复杂的基于match的代码来检查每种可能的组合吗?

extern crate serialize;

static JSON: &'static str  = r#"
    {
        "status": {
            "status": "OK"
        },
        "data": {
            "container": {
                "key": "value",
                "list": [
                    {
                        "key1": "value1",
                        "key2": "value2"
                    },
                    {
                        "key1": "value1"
                    }
                ]
            }
        }
    }"#;
#[deriving(Decodable, Show)]
struct Top {
    status: Status,
    data: Data,
}

#[deriving(Decodable, Show)]
struct Data {
    container: Container,
}

#[deriving(Decodable, Show)]
struct Status {
    status: String,
}

#[deriving(Decodable, Show)]
struct Container {
    key: String,
    list: Vec<KeyVals>,
}

#[deriving(Decodable, Show)]
struct KeyVals {
    key1: String,
    key2: String,
}

fn main() {
    let result: Top = match serialize::json::decode(JSON) {
        Ok(x) => x,
        Err(why) => fail!("Failed decoding the JSON! Reason: {}", why),
    };
    println!("{}", result);
}

运行代码时,它会失败,因为列表的第二个元素缺少key2属性。

task '<main>' failed at 'Failed decoding the JSON! Reason: MissingFieldError(key2)', hello.rs:56

谢谢

1 个答案:

答案 0 :(得分:3)

潜在的现有数据可以通过枚举表示。在最简单的情况下,使用Option

我相信使用枚举也可以解决您的问题。

#[deriving(Encodable, Decodable)]
enum Status {
    Good(Container),
    Bad,
    VeryBad
}

如果Container还包含可能存在的数据,那么您可以再次使用枚举来表示该数据。