rustless 0.1.2

Rustless is a REST-like API micro-framework for Rust.
use std::io::{Reader, IoResult, File, MemReader};
use serialize::json::Json;

use server::header::{Headers, Header, HeaderFormat};
use server::header::common::{ContentType};
use server::mime::{Mime, TopLevel, SubLevel};
use server::status::StatusCode;
use typemap::TypeMap;
use {Extensible};

pub struct Response {
    pub status: StatusCode,
    pub headers: Headers,
    pub body: Option<Box<Reader + Send>>,
    pub ext: TypeMap
}

impl Response {

    pub fn new(status: StatusCode) -> Response {
        Response {
            status: status,
            headers: Headers::new(),
            body: None,
            ext: TypeMap::new()
        }
    }

    #[allow(dead_code)]
    pub fn from_reader(status: StatusCode, body: Box<Reader + Send>) -> Response {
        Response {
            status: status,
            headers: Headers::new(),
            body: Some(body),
            ext: TypeMap::new()
        }
    }

    pub fn from_string(status: StatusCode, body: String) -> Response {
        let mut response = Response::new(status);
        response.push_string(body);
        response
    }

    pub fn set_header<H: Header + HeaderFormat>(&mut self, header: H) {
        self.headers.set(header);
    }

    pub fn set_json_content_type(&mut self) {
        self.set_header(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])));
    }

    pub fn from_json(status: StatusCode, body: &Json) -> Response {
        let mut response = Response::new(status);
        response.set_json_content_type();
        response.push_string(body.to_string());
        response
    }

    pub fn push_string(&mut self, body: String) {
        self.body = Some(box MemReader::new(body.into_bytes()) as Box<Reader + Send>)
    }

    pub fn push_file(&mut self, path: &Path) -> IoResult<()> {
        let reader = box try!(File::open(path));
        self.body = Some(reader as Box<Reader + Send>);

        Ok(())
    }

    #[allow(dead_code)]
    pub fn from_file(path: &Path) -> IoResult<Response> {
        let mut response = Response::new(StatusCode::Ok);
        try!(response.push_file(path));
        Ok(response)
    }

    pub fn ext(&self) -> &TypeMap {
        &self.ext
    }

    pub fn ext_mut(&mut self) -> &mut TypeMap {
        &mut self.ext
    }

}

impl_extensible!(Response)

impl Reader for Response {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        match self.body {
            Some(ref mut reader) => reader.read(buf),
            None => Ok(0u)
        }
    }
}