use hyper;
use futures::{self, Stream, Future};
use serde;
use serde_json;
use error;
pub mod params;
pub mod url_parser;
pub use self::params::Params;
#[derive(Debug)]
pub enum Error {
Serde(serde_json::Error),
Hyper(hyper::Error),
}
impl From<Error> for error::Error {
fn from(err: Error) -> Self {
error::Error::bad_request(
"Unable to parse request as JSON.",
format!("{:?}", err),
)
}
}
#[derive(Debug)]
pub struct Request<P = ()> {
request: hyper::Request,
params: Option<P>,
}
impl<P> Request<P> {
pub fn new(request: hyper::Request, params: P) -> Self {
Request { request, params: Some(params) }
}
pub fn params(&self) -> &P {
self.params.as_ref().unwrap()
}
pub fn take_params(&mut self) -> P {
self.params.take().unwrap()
}
pub fn json<T>(self) -> JsonResult<T> where
T: for<'a> serde::de::Deserialize<'a>,
{
self.request.body().concat2().then(deserialize)
}
}
fn deserialize<T: for<'a> serde::de::Deserialize<'a>>(chunk: Result<hyper::Chunk, hyper::Error>) -> Result<T, Error> {
match chunk {
Ok(chunk) => match serde_json::from_slice(&*chunk) {
Ok(res) => Ok(res),
Err(err) => Err(Error::Serde(err)),
},
Err(err) => Err(Error::Hyper(err)),
}
}
type JsonResult<T> = futures::Then<
futures::stream::Concat2<hyper::Body>,
Result<T, Error>,
fn(Result<hyper::Chunk, hyper::Error>) -> Result<T, Error>,
>;