Hi,
I'm implementing an application that interacts with an existing json web service and have some problems with returning custom errors.
The challenge is that the json returned by the web service contains optional fields which may not exist.
I use the rustc_serialize crate but due to the optional fields I can't use #[derive(RustcDecodable)] because it would expect those fields. (?)
Therefore, I'm currently implementing the Decodable Trait:
struct A {
mandatory: String,
optional: Option<String>,
}
impl rustc_serialize::Decodable for A {
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
d.read_map(|s, len| {
let mandatory: Option<String> = None;
let optional: Option<String> = None;
for x in 1..len {
let key = try!(s.read_map_elt_key(x-1, |s| s.read_str())).as_ref();
match key {
"mandatory" => mandatory = Some(try!(s.read_map_elt_val(x-1, |s| s.read_str()))),
"optional" => optional = Some(try!(s.read_map_elt_val(x-1, |s| s.read_str()))),
_ => {
let msg = String::from("Unexpected key: ");
msg.push_str(key);
return Err(rustc_serialize::json::DecoderError::UnknownVariantError(msg));
}
}
}
Ok(A {
mandatory: mandatory.unwrap(),
optional: optional,
})
})
}
}
This won't compile:
src/lib.rs:173 return Err(rustc_serialize::json::DecoderError::UnknownVariantError(msg));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:173:20: 173:81 help: run `rustc --explain E0308` to see a detailed explanation
src/lib.rs:173:20: 173:81 note: expected type `<D as rustc_serialize::Decoder>::Error`
src/lib.rs:173:20: 173:81 note: found type `rustc_serialize::json::DecoderError`
I understand the issue. D::Error is an unbound associated type and rustc_serialize::json::DecoderError::UnknownVariantError(msg) is something completely different.
Specifying that I expect Error to be of that type conflicts with the Trait implementation:
fn decode<D: rustc_serialize::Decoder<Error=rustc_serialize::json::DecoderError>>(d: &mut D) -> Result<Self, D::Error>
But how am I supposed to return my 'Unknown key' error while still implementing the Trait then?