如何从Rust中的JSON反序列化& str结构字段

时间:2014-08-14 08:17:03

标签: json string serialization deserialization rust

我正在从JSON反序列化结构:

fn main() {
  let raw_json = r#"{"error": {"msg": "I am an error message"}}"#;
  let error: Error = json::decode(raw_json).unwrap();

}

struct Error {
  message: &'static str
}

impl<D: Decoder<E>, E> Decodable<D, E> for Error {
  fn decode(d: &mut D) -> Result<Error, E> {
    d.read_struct("error", 1, |d| {
      Ok(Error{
        message: try!(d.read_struct_field("msg", 0u, |d| Decodable::decode(d)))
      })
    })
  }
}

但是得到了这个错误:

failed to find an implementation of trait serialize::serialize::Decodable<D,E> for &'static str

将生命周期添加到message无济于事。 事实证明Decodable没有实现&str特征,但只适用于String

如何将我的JSON反序列化为&str struct field?

2 个答案:

答案 0 :(得分:3)

参考文献无法序列化或反序列化。需要采用不同的方法。

您的错误结构包含&'static str。这意味着您还可以以枚举的形式表示错误,这可以序列化。然后你可以实现Show for Error。

extern crate serialize;
use serialize::{Decodable, Encodable};
use std::fmt;

#[deriving(Encodable, Decodable)]
enum Error {
    Foo,
    Bar
}

impl fmt::Show for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Foo => write!(f, "Foo happened"),
            Bar => write!(f, "Bar happened"),
        }
    }
}

问题是这是否真的是你想要的。如果您希望能够表示任意错误消息(而不是特定的错误类型),那么您将不得不使用String。

extern crate serialize;
use serialize::{Decodable, Encodable};

#[deriving(Encodable, Decodable)]
struct Error {
    msg: String
}

答案 1 :(得分:2)

对于&'static str,您必须有一个字符串文字,一个持续整个过程生命周期的字符串(永远是a.k.a.)。这显然无法实现。

对于&'a str通常,其他内容必须拥有字节 - 它通常是String的某些内容的引用(也可能是Vec<Ascii>或可能是标准库外的另一个类似的UTF-8字符串类型)。这不是序列化工作的方式 - 不一定存储永久存储的值,因此它不能产生引用。这就是为什么它仅针对String实施的原因:您根本无法将其用于&str