如何实现字段值为另一个结构的rustc_serialize::Decodable for struct?

如何实现字段值为另一个结构的rustc_serialize::Decodable for struct?,struct,rust,Struct,Rust,我需要为我的Herdstruct实现rustc\u serialize::Decoder特性: extern crate chrono; extern crate rustc_serialize; use chrono::NaiveDate; use rustc_serialize::Decodable; struct Herd { id: i32, breed: String, name: String, purchase_date: NaiveDate,

我需要为我的
Herd
struct实现
rustc\u serialize::Decoder
特性:

extern crate chrono;
extern crate rustc_serialize;

use chrono::NaiveDate;
use rustc_serialize::Decodable;

struct Herd {
    id: i32,
    breed: String,
    name: String,
    purchase_date: NaiveDate,
}

impl Decodable for Herd {
    fn decode<D: Decoder>(d: &mut D) -> Result<Herd, D::Error> {
        d.read_struct("Herd", 4, |d| {
            let id = try!(d.read_struct_field("id", 0, |d| d.read_i32()));
            let breed = try!(d.read_struct_field("breed", 1, |d| d.read_str()));
            let name = try!(d.read_struct_field("name", 2, |d| d.read_str()));
            let purchase_date = try!(d.read_struct_field("purchase_date", 3, |i| {
                i.read_struct("NaiveDate", 1, |i| {
                    let ymdf = try!(i.read_struct_field("ymdf", 0, |i| i.read_i32()));
                    Ok(NaiveDate { ymdf: ymdf })
                })
            }));

            Ok(Herd {
                id: id,
                breed: breed,
                name: name,
                purchase_date: purchase_date,
            })
        })
    }
}
我正在手动实现
可解码的
,这就是您在上面代码中看到的。是具有一个数据类型为i32的字段的结构

当我现在运行代码时,我收到消息:

struct chrono::NaiveDate的字段ymdf是私有的

如何为
date
实现
解码器
?对于我的
Herd
struct,是否有一种更简单的方法来实现
Decodable
?我是一个全面的初学者程序员;也许有另一种方式来看待这个问题

我使用的Rust 1.12具有以下依赖项:

  • nickel=“0.9.0”
  • postgres={version=“0.12”,功能=[“with chrono”]}
  • chrono=“0.2”
  • rustc serialize=“0.3”

为了能够
群体
导出
可解码
原始日期
也需要是
可解码的
。但是,它的
ymdf
字段是私有的,如果您想手动实现它,这是一个问题

您可以为
ymdf
(并在
Herd
中使用它)定义您自己的包装器类型-然后您应该能够
为它派生
可解码的
,然后为
Herd

编辑:这不一定是使用
NaiveDate
的方法,因为没有简单的方法将
ymdf
转换成它(或导入
DateImpl
,它的类型),但根据您的需要,以下方法可能就足够了:

use std::i32;

pub type DateImpl = i32;
pub const MAX_YEAR: DateImpl = i32::MAX >> 13;
pub const MIN_YEAR: DateImpl = i32::MIN >> 13;

#[derive(RustcDecodable)]
struct YmdfWrapper {
    ymdf: DateImpl
}

#[derive(RustcDecodable)]
struct Herd {
    id: i32,
    breed: String,
    name: String,
    purchase_date: YmdfWrapper,
}

为了能够
群体
导出
可解码
原始日期
也需要是
可解码的
。但是,它的
ymdf
字段是私有的,如果您想手动实现它,这是一个问题

您可以为
ymdf
(并在
Herd
中使用它)定义您自己的包装器类型-然后您应该能够
为它派生
可解码的
,然后为
Herd

编辑:这不一定是使用
NaiveDate
的方法,因为没有简单的方法将
ymdf
转换成它(或导入
DateImpl
,它的类型),但根据您的需要,以下方法可能就足够了:

use std::i32;

pub type DateImpl = i32;
pub const MAX_YEAR: DateImpl = i32::MAX >> 13;
pub const MIN_YEAR: DateImpl = i32::MIN >> 13;

#[derive(RustcDecodable)]
struct YmdfWrapper {
    ymdf: DateImpl
}

#[derive(RustcDecodable)]
struct Herd {
    id: i32,
    breed: String,
    name: String,
    purchase_date: YmdfWrapper,
}

NaiveDate
确实实现了
可解码
,但在可选功能
下实现了“rustc serialize”

您应该将其添加到您的
Cargo.toml
中以激活它:

chrono = { version = "0.2", features = ["rustc-serialize"]}

NaiveDate
确实实现了
可解码
,但在可选功能
下实现了“rustc serialize”

您应该将其添加到您的
Cargo.toml
中以激活它:

chrono = { version = "0.2", features = ["rustc-serialize"]}

要实现
可解码
Herd
不需要所有字段都是
可解码的
。只有当你想获得一种特质时,这才是必需的。在这种情况下,手动实现trait会更容易。我认为如果能给出一个如何实现的片段,这个答案会更好。这也是回答OP提出的一般性问题的唯一答案,不是我想要的特定实例^ ^@Shepmaster,而是让我很难用
extern-crater
s测试代码,我不想让一些错误溜走。当我有时间和合适的网络时,我会加上它。@mcarton我差点忘了;我按照你的建议修正了答案。。并非所有游乐场的创建都是相同的。要实现
可解码
牧群
不需要其所有字段都是
可解码的
。只有当你想获得一种特质时,这才是必需的。在这种情况下,手动实现trait会更容易。我认为如果能给出一个如何实现的片段,这个答案会更好。这也是回答OP提出的一般性问题的唯一答案,不是我想要的特定实例^ ^@Shepmaster,而是让我很难用
extern-crater
s测试代码,我不想让一些错误溜走。当我有时间和合适的网络时,我会加上它。@mcarton我差点忘了;我按照你的建议修正了答案。。并非所有的游乐场都是平等的。