diff --git a/src/client/response.rs b/src/client/response.rs index f3067d6..bca915c 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -3,7 +3,7 @@ use std::error::Error; use std::fmt; -use rustc_serialize::json::Json; +use rustc_serialize::json::{self, Json}; /// Response parsing. pub trait FromResponse: Sized { @@ -54,3 +54,29 @@ impl fmt::Display for ParseError { impl Error for ParseError { fn description(&self) -> &str { "response parse error" } } + +/// JSON helper for response parsing. +#[derive(Debug)] +pub struct JsonHelper<'a>(pub &'a Json); + +impl<'a> JsonHelper<'a> { + /// Returns self as a `JsonObjectHelper` or fails with `ParseError::ExpectedType`. + pub fn as_object(&self) -> Result, ParseError>{ + self.0.as_object() + .ok_or(ParseError::ExpectedType("object")) + .map(|o| JsonObjectHelper(o)) + } +} + +/// JSON object helper for response parsing. +#[derive(Debug)] +pub struct JsonObjectHelper<'a>(pub &'a json::Object); + +impl<'a> JsonObjectHelper<'a> { + /// Gets a field as a string or fails with `ParseError::ExpectedFieldType`. + pub fn get_string(&self, key: &'static str) -> Result<&'a str, ParseError> { + self.0.get(key) + .and_then(Json::as_string) + .ok_or(ParseError::ExpectedFieldType(key, "string")) + } +}