use std::io::{File, MemReader};
use std::path::Path;
use modifier::Modifier;
use hyper::mime::Mime;
use {status, headers, Response, Url};
pub struct ContentType(pub Mime);
impl ContentType {
#[inline]
pub fn new(m: Mime) -> ContentType {
ContentType(m)
}
}
impl Modifier<Response> for ContentType {
#[inline]
fn modify(self, res: &mut Response) {
let ContentType(media) = self;
res.headers.set(headers::ContentType(media))
}
}
pub struct Body<B: Bodyable>(pub B);
impl<B: Bodyable> Modifier<Response> for Body<B> {
#[inline]
fn modify(self, res: &mut Response) {
let Body(b) = self;
b.set_body(res);
}
}
pub trait Bodyable {
fn set_body(self, res: &mut Response);
}
impl Bodyable for Box<Reader + Send> {
#[inline]
fn set_body(self, res: &mut Response) {
res.body = Some(self);
}
}
impl Bodyable for String {
#[inline]
fn set_body(self, res: &mut Response) {
self.into_bytes().set_body(res);
}
}
impl Bodyable for Vec<u8> {
#[inline]
fn set_body(self, res: &mut Response) {
res.headers.set(headers::ContentLength(self.len()));
res.body = Some(box MemReader::new(self) as Box<Reader + Send>);
}
}
impl<'a> Bodyable for &'a str {
#[inline]
fn set_body(self, res: &mut Response) {
self.into_string().set_body(res);
}
}
impl<'a> Bodyable for &'a [u8] {
#[inline]
fn set_body(self, res: &mut Response) {
self.to_vec().set_body(res);
}
}
impl Bodyable for File {
#[inline]
fn set_body(self, res: &mut Response) {
res.body = Some(box self as Box<Reader + Send>);
}
}
impl Bodyable for Path {
fn set_body(self, res: &mut Response) {
File::open(&self)
.ok().expect(format!("No such file: {}", self.display()).as_slice())
.set_body(res);
}
}
pub struct Status(pub status::Status);
impl Modifier<Response> for Status {
fn modify(self, res: &mut Response) {
let Status(status) = self;
res.status = Some(status);
}
}
pub struct Redirect(pub Url);
impl Modifier<Response> for Redirect {
fn modify(self, res: &mut Response) {
let Redirect(url) = self;
res.headers.set(headers::Location(url.to_string()));
}
}