我已经阅读过Valve JSON Serialization in Rust, Part 1并尝试运行博客中的代码。最复杂的部分是为自定义结构执行自定义序列化。
我更新了代码段,以便它可以在最新的Rust上运行:
extern crate rustc_serialize;
use rustc_serialize::{json, Encodable, Encoder};
struct Person {
name: String,
age: usize,
}
impl Encodable for Person {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
match *self {
Person { name: ref p_name, age: ref p_age, } => {
s.emit_struct("Person", 0, |s| {
try!(s.emit_struct_field( "name", 0, |s| p_name.encode(s)));
try!(s.emit_struct_field( "age", 1, |s| p_age.encode(s)));
try!(s.emit_struct_field( "summary", 2, |s| {
(format!("Nice person named {}, {} years of age", p_name, p_age)).encode(s)
}));
Ok(())
})
},
}
}
}
fn main() {
let person = Person {
name: "John Doe".to_string(),
age: 33,
};
println!("{}" , json::encode(&person).unwrap());
}
上面的输出是{}
,但正确的结果应该是:
{"age":33,"name":"John Doe","summary":"Nice person named John Doe, 33 years of age"}
我想知道如何使用Encodable
特征以正确的方式序列化自定义结构。
谢谢。
答案 0 :(得分:3)
看起来你的教程已经过时了。它说
我们在编码器上调用emit_struct并传递3个参数:struct的名称,当前索引和匿名函数(aka lambda)。不使用结构的名称; 当前索引未被使用。
fn emit_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodeResult<()> where
F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>,
{
if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
if len == 0 {
try!(write!(self.writer, "{{}}"));
因此,参数已从索引更改为 length ,现在它有意义了。这是你工作的例子:
extern crate rustc_serialize;
use rustc_serialize::{json, Encodable, Encoder};
struct Person {
name: String,
age: usize,
}
impl Encodable for Person {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("Person", 1, |s| {
try!(s.emit_struct_field("name", 0, |s| self.name.encode(s)));
try!(s.emit_struct_field("age", 1, |s| self.age.encode(s)));
try!(s.emit_struct_field("summary", 2, |s| {
let summary = format!("Nice person named {}, {} years of age", self.name, self.age);
summary.encode(s)
}));
Ok(())
})
}
}
fn main() {
let person = Person {
name: "John Doe".to_string(),
age: 33,
};
println!("{}" , json::encode(&person).unwrap());
}
请注意,我还删除了疯狂的旋转来解构self
并直接访问属性。
答案 1 :(得分:2)
问题在于emit_struct(..)
来电。
此功能的原型是:
fn emit_struct<F>(&mut self, name: &str, len: usize, f: F)
-> Result<(), Self::Error>
where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
此处,len
是结构的字段数。你把它设置为0
,因此生成的JSON字典有0个字段。
将其更改为3可得出此输出:
{"name":"John Doe","age":33,"summary":"Nice person named John Doe, 33 years of age"}