使用枚举成员

时间:2016-02-01 15:52:08

标签: json rust deserialization serde

我想尝试一些看起来像这样的json:

{
    "foo": "bar",
    "name": "some name"
}

并使用serde将其反序列化为如下数据结构:

#[derive(Clone, PartialEq, Debug)]
pub struct Quux {
    foo: Foo,
    name: String,

}

pub enum Foo {
    Bar,
    Baz,
}

have some code,但说实话,它几乎直接来自serde指南“无宏反序列化”,而且我不确定我到底需要做什么让它将foo字段反序列化为Foo

我已为Deserialize枚举实施了Foo,我认为这足以让我visitor.visit_value()中的impl serde::de::Vistor for QuuxVisitor来电调deserialize版本Quux },但似乎并非如此。

我尝试反序列化为called 'Result::unwrap()' on an 'Err' value: SyntaxError("expected value", 2, 20)时遇到的错误是Quux,但如果我更改String以使用foo代替Foo而不是一个set.seed(123) x = sort(unique(floor(runif(1e6, 1, 1e7)))) y = sample(1e7, 10000) ,它反序列化很好。

3 个答案:

答案 0 :(得分:2)

这是一个例子。我不确定处理未知字段的最佳方法,但这有效:

extern crate serde;

use serde::de::{Deserialize, Deserializer, Visitor, Error};

pub enum Foo {
    Bar,
    Baz,
}

impl Deserialize for Foo {
    fn deserialize<D>(deserializer: &mut D) -> Result<Foo, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = Foo;

            fn visit_str<E>(&mut self, value: &str) -> Result<Foo, E>
                where E: Error
            {
                match value {
                    "bar" => Ok(Foo::Bar),
                    "baz" => Ok(Foo::Baz),
                    _ => Err(E::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

我使用了Rust 1.6。

答案 1 :(得分:2)

Rust 1.18 / serde 1.0.0有一个完整的例子:

"a[title='Permit']"

您可以看到类似的示例here

答案 2 :(得分:1)

我建议使用serde_derive来生成Deserialize实现,而不要手工写出来。

在下面的代码中,我使用#[serde(rename_all = "lowercase")]来使Foo接受JSON表示形式"bar""baz"而不是默认的"Bar"和{{ 1}}对应于Rust代码中的大写字母。

"Baz"