monto/common/
mod.rs

1//! Functions and types useful for implementing both the Client and Service
2//! Protocols.
3
4pub mod messages;
5pub mod products;
6
7use either::{Either, Left, Right};
8use futures::{Future, Stream};
9use futures::future::{err, ok};
10use hyper::{Body, Response, StatusCode};
11use hyper::Error as HyperError;
12use hyper::header::{ContentLength, ContentType};
13use serde::Serialize;
14use serde::de::DeserializeOwned;
15use serde_json;
16use serde_json::error::Error as SerdeError;
17
18/// Creates an error response.
19pub fn error_response(
20    status: StatusCode,
21) -> Box<Future<Item = Response<Body>, Error = HyperError>> {
22    let res = status.to_string();
23    Box::new(ok(
24        Response::new()
25            .with_status(status)
26            .with_header(ContentLength(res.len() as u64))
27            .with_header(ContentType("text/plain".parse().unwrap()))
28            .with_body(res),
29    ))
30}
31
32/// Deserializes an object as JSON from the request.
33pub fn json_request<T: DeserializeOwned + 'static>(
34    body: Body,
35) -> Box<Future<Item = T, Error = Either<HyperError, SerdeError>>> {
36    Box::new(body.concat2().map_err(Left).and_then(|bs| {
37        serde_json::from_slice(&*bs).map_err(Right)
38    }))
39}
40
41/// Converts an object to JSON and serves it as a Response.
42pub fn json_response<T: Serialize>(
43    t: T,
44    status: StatusCode,
45) -> Box<Future<Item = Response<Body>, Error = Either<HyperError, SerdeError>>> {
46    let res = match serde_json::to_string(&t) {
47        Ok(s) => s,
48        Err(e) => return Box::new(err(Right(e))),
49    };
50    Box::new(ok(
51        Response::new()
52            .with_status(status)
53            .with_header(ContentLength(res.len() as u64))
54            .with_header(ContentType("application/json".parse().unwrap()))
55            .with_body(res),
56    ))
57}