pub extern crate semver;
use std::io::prelude::*;
use std::io;
use std::collections::HashMap;
use std::error::Error;
use std::net::SocketAddr;
use std::fmt;
pub use self::typemap::TypeMap;
mod typemap;
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum Scheme {
Http,
Https
}
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum Host<'a> {
Name(&'a str),
Socket(SocketAddr)
}
#[derive(PartialEq, Hash, Eq, Debug, Clone)]
pub enum Method {
Get,
Post,
Put,
Delete,
Head,
Connect,
Options,
Trace,
Patch,
Purge,
Other(String)
}
impl fmt::Display for Method {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let s = match *self {
Method::Get => "GET",
Method::Post => "POST",
Method::Put => "PUT",
Method::Delete => "DELETE",
Method::Head => "HEAD",
Method::Connect => "CONNECT",
Method::Options => "OPTIONS",
Method::Trace => "TRACE",
Method::Patch => "PATCH",
Method::Purge => "PURGE",
Method::Other(ref s) => s,
};
fmt.write_str(s)
}
}
pub type Extensions = TypeMap;
pub trait Request {
fn http_version(&self) -> semver::Version;
fn conduit_version(&self) -> semver::Version;
fn method(&self) -> Method;
fn scheme(&self) -> Scheme;
fn host<'a>(&'a self) -> Host<'a>;
fn virtual_root<'a>(&'a self) -> Option<&'a str>;
fn path<'a>(&'a self) -> &'a str;
fn query_string<'a>(&'a self) -> Option<&'a str>;
fn remote_addr(&self) -> SocketAddr;
fn content_length(&self) -> Option<u64>;
fn headers<'a>(&'a self) -> &'a dyn Headers;
fn body<'a>(&'a mut self) -> &'a mut dyn Read;
fn extensions<'a>(&'a self) -> &'a Extensions;
fn mut_extensions<'a>(&'a mut self) -> &'a mut Extensions;
}
pub trait Headers {
fn find(&self, key: &str) -> Option<Vec<&str>>;
fn has(&self, key: &str) -> bool;
fn all(&self) -> Vec<(&str, Vec<&str>)>;
}
pub struct Response {
pub status: (u32, &'static str),
pub headers: HashMap<String, Vec<String>>,
pub body: Box<dyn WriteBody + Send>
}
pub trait Handler: Sync + Send + 'static {
fn call(&self, request: &mut dyn Request) -> Result<Response, Box<dyn Error+Send>>;
}
impl<F, E> Handler for F
where F: Fn(&mut dyn Request) -> Result<Response, E> + Sync + Send + 'static,
E: Error + Send + 'static
{
fn call(&self, request: &mut dyn Request) -> Result<Response, Box<dyn Error+Send>> {
(*self)(request).map_err(|e| Box::new(e) as Box<dyn Error+Send>)
}
}
pub trait WriteBody {
fn write_body(&mut self, out: &mut dyn Write) -> io::Result<u64>;
}
impl<R> WriteBody for R
where R: Read
{
fn write_body(&mut self, out: &mut dyn Write) -> io::Result<u64> {
io::copy(self, out)
}
}