finchers-json 0.6.0

JSON parsing/responder support for finchers
//!
//! JSON support (parsing/responder) based on serde_json
//!

extern crate finchers;
extern crate serde;
extern crate serde_json;

// TODO: make the dependency for hyper through finchers, rather than directly dependency.
extern crate hyper;

pub use self::serde_json::{Error, Value};

use hyper::{header, mime};
use self::serde::ser::Serialize;
use self::serde::de::DeserializeOwned;

use finchers::endpoint::body::{body, Body};
use finchers::request::{FromBody, Request};
use finchers::response::{Responder, Response};


/// Represents a JSON value
#[derive(Debug)]
pub struct Json<T = Value>(pub T);

impl<T: DeserializeOwned> FromBody for Json<T> {
    type Error = Error;

    fn check_request(req: &Request) -> bool {
        req.media_type()
            .map_or(false, |m| *m == mime::APPLICATION_JSON)
    }

    fn from_body(body: Vec<u8>) -> Result<Self, Self::Error> {
        serde_json::from_slice(&body).map(Json)
    }
}

impl<T: Serialize> Responder for Json<T> {
    type Error = Error;

    fn respond(self) -> Result<Response, Self::Error> {
        let body = serde_json::to_vec(&self.0)?;
        let len = body.len();
        Ok(Response::new()
            .with_header(header::ContentType::json())
            .with_header(header::ContentLength(len as u64))
            .with_body(body))
    }
}

/// Create an endpoint with parsing JSON body
pub fn json_body<T: DeserializeOwned>() -> Body<Json<T>> {
    body::<Json<T>>()
}