構造体のフィールドの1つがオブジェクトまたはデータベース内のそのオブジェクトのIDのいずれかになるJSON構造を持っています。文書は、構造体の両方の可能なフォーマットで、次のようになりましょう:私は、このためのカスタムデコーダを実装するための最良の方法を把握しようとしているrustc-serializeカスタムenumデコード
。これまでのところ、私はいくつかの異なる方法を試してみた、と私は現在、ここにこだわっ:
extern crate rustc_serialize;
use rustc_serialize::{Decodable, Decoder, json};
#[derive(RustcDecodable, Debug)]
struct Car {
id: u64,
color: String
}
#[derive(Debug)]
enum OCar {
Id(u64),
Car(Car)
}
#[derive(Debug)]
struct Person {
name: String,
car: OCar
}
impl Decodable for Person {
fn decode<D: Decoder>(d: &mut D) -> Result<Person, D::Error> {
d.read_struct("root", 2, |d| {
let mut car: OCar;
// What magic must be done here to get the right OCar?
/* I tried something akin to this:
let car = try!(d.read_struct_field("car", 0, |r| {
let r1 = Car::decode(r);
let r2 = u64::decode(r);
// Compare both R1 and R2, but return code for Err() was tricky
}));
*/
/* And this got me furthest */
match d.read_struct_field("car", 0, u64::decode) {
Ok(x) => {
car = OCar::Id(x);
},
Err(_) => {
car = OCar::Car(try!(d.read_struct_field("car", 0, Car::decode)));
}
}
Ok(Person {
name: try!(d.read_struct_field("name", 0, Decodable::decode)),
car: car
})
})
}
}
fn main() {
// Vector of both forms
let input = "[{\"name\":\"pebbles\",\"car\":1},{\"name\":\"pebbles\",\"car\":{\"id\":1,\"color\":\"green\"}}]";
let output: Vec<Person> = json::decode(&input).unwrap();
println!("Debug: {:?}", output);
}
上記のパニックをセンチネル値rustcシリアル化は、そのエラー列挙型のいくつかに使用しているEOLと。フルラインは
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: EOF', src/libcore/result.rs:785
これは正しい方法はありますか?
非常に良い答え
はここで完全な例です!私は掘り出しながらスタックに気づいたが、データを何回も引き出すか、エラーを投げることがそれに影響を与えるかを確認する時間を費やさなかった。しかし1つの問題:これはserde_macrosのため夜間モードになります。その周りに道がありますか? – RandomInsano
[安定した錆とserde_codegenでSerdeを使う](https://github.com/serde-rs/serde#using-serde-with-stable-rust-and-serde_codegen)を参照してください。 –