I have a JSON structure where one of the fields of a struct could be either an object, or that object's ID in the database. Let's say the document looks like this with both possible formats of the struct:
[ { "name":"pebbles", "car":1 }, { "name":"pebbles", "car":{ "id":1, "color":"green" } } ] I'm trying to figure out the best way to implement a custom decoder for this. So far, I've tried a few different ways, and I'm currently stuck here:
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); } The above panics with an EOL which is a sentinel value rustc-serialize uses on a few of its error enums. Full line is
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: EOF', src/libcore/result.rs:785 What's the right way to do this?