-
-
Save erickt/ec0c196dd3790ce1ee1cb16ca8faaa85 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(plugin, custom_derive)] | |
#![plugin(serde_macros)] | |
extern crate serde; | |
extern crate serde_json; | |
use std::error::Error; | |
use serde::de::Error as SerdeError; | |
use serde_json::Value; | |
pub enum Foo { | |
Stuff(Stuff), | |
OtherStuff(OtherStuff), | |
} | |
#[derive(Deserialize)] | |
pub struct Stuff { | |
pub stuff: u32, | |
} | |
#[derive(Deserialize)] | |
pub struct OtherStuff { | |
pub stuff: u32, | |
} | |
macro_rules! try_conv { | |
($expr:expr) => (match $expr { | |
Ok(val) => val, | |
Err(err) => { | |
use std::error::Error; | |
return Err(D::Error::custom(err.description())) | |
} | |
}) | |
} | |
impl serde::Deserialize for Foo { | |
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> | |
where D: serde::Deserializer | |
{ | |
let value: Value = try!(Value::deserialize(deserializer)); | |
enum ClassType { | |
Stuff, | |
OtherStuff, | |
} | |
// XXX find a solution to get rid of this clone | |
let kind = match value.find("classtype") { | |
Some(&Value::String(ref s)) => { | |
match &**s { | |
"stuff" => { ClassType::Stuff } | |
"otherstuff" => { ClassType::OtherStuff } | |
_ => { | |
return Err(D::Error::custom("invalid")); | |
} | |
} | |
} | |
Some(_) => { | |
return Err(D::Error::custom("non-string 'classtype'")) | |
} | |
None => { | |
return Err(D::Error::missing_field("classtype")); | |
} | |
}; | |
match kind { | |
ClassType::Stuff => { | |
let stuff: Stuff = try_conv!(serde_json::from_value(value)); | |
Ok(Foo::Stuff(stuff)) | |
} | |
ClassType::OtherStuff => { | |
let other_stuff: OtherStuff = try_conv!(serde_json::from_value(value)); | |
Ok(Foo::OtherStuff(other_stuff)) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment