use std::collections::HashMap;
use std::iter::{Iterator, FlatMap};
use std::str::SplitTerminator;
use std::slice::Iter;
use std::ops::Deref;
use hyper::method::Method;
use handler::Handler;
use context::Hypermedia;
pub use self::tree_router::TreeRouter;
mod tree_router;
pub struct Endpoint<'a, T: 'a> {
pub handler: Option<&'a T>,
pub variables: HashMap<String, String>,
pub hypermedia: Hypermedia<'a>
}
impl<'a, T> From<Option<&'a T>> for Endpoint<'a, T> {
fn from(handler: Option<&'a T>) -> Endpoint<'a, T> {
Endpoint {
handler: handler,
variables: HashMap::new(),
hypermedia: Hypermedia::new()
}
}
}
pub trait Router: Send + Sync + 'static {
type Handler: Handler;
fn insert<'r, R: Route<'r> + ?Sized>(&mut self, method: Method, route: &'r R, handler: Self::Handler);
fn find<'a: 'r, 'r, R: Route<'r> + ?Sized>(&'a self, method: &Method, route: &'r R) -> Endpoint<'a, Self::Handler>;
}
impl<H: Handler> Router for H {
type Handler = H;
fn find<'a: 'r, 'r, R: Route<'r> + ?Sized>(&'a self, _method: &Method, _route: &'r R) -> Endpoint<'a, H> {
Some(self).into()
}
fn insert<'r, R: Route<'r> + 'r + ?Sized>(&mut self, _method: Method, _route: &'r R, _handler: H) {}
}
pub trait Route<'a> {
type Segments: Iterator<Item=&'a str>;
fn segments(&'a self) -> <Self as Route<'a>>::Segments;
}
impl<'a> Route<'a> for str {
type Segments = RouteIter<SplitTerminator<'a, char>>;
fn segments(&'a self) -> <Self as Route<'a>>::Segments {
let s = if self.starts_with('/') {
&self[1..]
} else {
self
};
if s.len() == 0 {
RouteIter::Root
} else {
RouteIter::Path(s.split_terminator('/'))
}
}
}
impl<'a, R: Route<'a>> Route<'a> for [R] {
type Segments = FlatMap<Iter<'a, R>, <R as Route<'a>>::Segments, fn(&'a R) -> <R as Route<'a>>::Segments>;
fn segments(&'a self) -> <Self as Route>::Segments {
fn segments<'a, T: Route<'a> + 'a>(s: &'a T) -> <T as Route<'a>>::Segments {
s.segments()
}
self.iter().flat_map(segments::<'a>)
}
}
impl<'a, 'b: 'a, T: Deref<Target=R> + 'b, R: Route<'a> + ?Sized + 'b> Route<'a> for T {
type Segments = <R as Route<'a>>::Segments;
#[inline]
fn segments(&'a self) -> <Self as Route<'a>>::Segments {
self.deref().segments()
}
}
pub enum RouteIter<I: Iterator> {
Root,
Path(I)
}
impl<I: Iterator> Iterator for RouteIter<I> {
type Item = <I as Iterator>::Item;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
match self {
&mut RouteIter::Path(ref mut i) => i.next(),
&mut RouteIter::Root => None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
&RouteIter::Path(ref i) => i.size_hint(),
&RouteIter::Root => (0, Some(0))
}
}
}