use std::collections::HashMap;
use std::io::{self, Read};
use std::net::SocketAddr;
#[cfg(feature = "rustc_json_body")]
use rustc_serialize::json;
#[cfg(feature = "rustc_json_body")]
use rustc_serialize::Decodable;
use hyper::http::HttpReader;
use hyper::net::NetworkStream;
use hyper::buffer::BufReader;
use utils;
use HttpVersion;
use Method;
use header::Headers;
use log::Log;
use Global;
pub struct Context<'a, 'b: 'a, 's> {
pub headers: Headers,
pub http_version: HttpVersion,
pub address: SocketAddr,
pub method: Method,
pub path: String,
pub hypermedia: Hypermedia<'s>,
pub variables: HashMap<String, String>,
pub query: HashMap<String, String>,
pub fragment: Option<String>,
pub log: &'s (Log + 's),
pub global: &'s Global,
pub body: BodyReader<'a, 'b>,
}
pub struct BodyReader<'a, 'b: 'a> {
request: HttpReader<&'a mut BufReader<&'b mut NetworkStream>>
}
impl<'a, 'b> BodyReader<'a, 'b> {
pub fn from_reader(request: HttpReader<&'a mut BufReader<&'b mut NetworkStream>>) -> BodyReader<'a, 'b> {
BodyReader {
request: request
}
}
}
impl<'a, 'b> Read for BodyReader<'a, 'b> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.request.read(buf)
}
}
pub trait ExtQueryBody {
fn read_query_body(&mut self) -> io::Result<HashMap<String, String>>;
}
impl<'a, 'b> ExtQueryBody for BodyReader<'a, 'b> {
#[inline]
fn read_query_body(&mut self) -> io::Result<HashMap<String, String>> {
let mut buf = Vec::new();
try!(self.read_to_end(&mut buf));
Ok(utils::parse_parameters(&buf))
}
}
#[cfg(feature = "rustc_json_body")]
pub trait ExtJsonBody {
fn read_json_body(&mut self) -> Result<json::Json, json::BuilderError>;
fn decode_json_body<T: Decodable>(&mut self) -> json::DecodeResult<T>;
}
#[cfg(feature = "rustc_json_body")]
impl<'a, 'b> ExtJsonBody for BodyReader<'a, 'b> {
fn read_json_body(&mut self) -> Result<json::Json, json::BuilderError> {
json::Json::from_reader(self)
}
fn decode_json_body<T: Decodable>(&mut self) -> json::DecodeResult<T> {
let mut buf = String::new();
try!(self.read_to_string(&mut buf).map_err(|e| {
let parse_err = json::ParserError::IoError(e);
json::DecoderError::ParseError(parse_err)
}));
json::decode(&buf)
}
}
pub struct Hypermedia<'a> {
pub links: Vec<Link<'a>>
}
impl<'a> Hypermedia<'a> {
pub fn new() -> Hypermedia<'a> {
Hypermedia {
links: vec![]
}
}
}
#[derive(PartialEq, Eq, Debug)]
pub struct Link<'a> {
pub method: Option<Method>,
pub path: Vec<LinkSegment<'a>>
}
#[derive(PartialEq, Eq, Debug)]
pub enum LinkSegment<'a> {
Static(&'a str),
Variable(&'a str),
RecursiveWildcard
}