2016-03-21 09:22:22 +00:00
|
|
|
use term_painter::ToStyle;
|
|
|
|
use term_painter::Color::*;
|
|
|
|
use std::fmt;
|
2016-03-21 04:27:17 +00:00
|
|
|
use method::Method;
|
2016-04-02 07:51:40 +00:00
|
|
|
use super::{Collider, URI, URIBuf}; // :D
|
|
|
|
use handler::Handler;
|
2016-03-21 04:27:17 +00:00
|
|
|
|
2016-03-28 09:34:09 +00:00
|
|
|
// TODO: Add ranking to routes. Give static routes higher rank by default.
|
2016-03-21 09:22:22 +00:00
|
|
|
// FIXME: Take in the handler! Or maybe keep that in `Router`?
|
2016-03-21 04:27:17 +00:00
|
|
|
pub struct Route {
|
2016-04-02 07:51:40 +00:00
|
|
|
pub method: Method,
|
2016-03-22 05:04:39 +00:00
|
|
|
pub handler: Handler<'static>,
|
2016-04-02 07:51:40 +00:00
|
|
|
pub path: URIBuf,
|
2016-03-22 05:04:39 +00:00
|
|
|
}
|
|
|
|
|
2016-03-21 04:27:17 +00:00
|
|
|
impl Route {
|
2016-04-02 07:51:40 +00:00
|
|
|
pub fn new(m: Method, path: String, handler: Handler<'static>) -> Route {
|
2016-03-21 04:27:17 +00:00
|
|
|
Route {
|
|
|
|
method: m,
|
2016-04-02 07:51:40 +00:00
|
|
|
path: URIBuf::new(path),
|
2016-03-22 05:04:39 +00:00
|
|
|
handler: handler,
|
2016-03-21 04:27:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-02 07:51:40 +00:00
|
|
|
pub fn set_path(&mut self, path: String) {
|
|
|
|
self.path = URIBuf::new(path);
|
2016-03-21 04:27:17 +00:00
|
|
|
}
|
|
|
|
|
2016-03-22 05:04:39 +00:00
|
|
|
// FIXME: Decide whether a component has to be fully variable or not. That
|
2016-03-28 09:34:09 +00:00
|
|
|
// is, whether you can have: /a<a>b/ or even /<a>:<b>/
|
2016-03-22 05:04:39 +00:00
|
|
|
// TODO: Don't return a Vec...take in an &mut [&'a str] (no alloc!)
|
|
|
|
pub fn get_params<'a>(&self, uri: &'a str) -> Vec<&'a str> {
|
2016-04-02 07:51:40 +00:00
|
|
|
let route_components = self.path.segments();
|
|
|
|
let uri_components = URI::new(uri).segments();
|
2016-03-22 05:04:39 +00:00
|
|
|
|
2016-04-02 07:51:40 +00:00
|
|
|
let mut result = Vec::with_capacity(self.path.segment_count());
|
|
|
|
for (route_seg, uri_seg) in route_components.zip(uri_components) {
|
|
|
|
if route_seg.starts_with("<") { // FIXME: Here.
|
|
|
|
result.push(uri_seg);
|
2016-03-22 05:04:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result
|
|
|
|
}
|
2016-03-21 04:27:17 +00:00
|
|
|
}
|
|
|
|
|
2016-03-21 09:22:22 +00:00
|
|
|
impl fmt::Display for Route {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "{} {:?}", Green.paint(&self.method), Blue.paint(&self.path))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-21 04:27:17 +00:00
|
|
|
impl Collider for Route {
|
|
|
|
fn collides_with(&self, b: &Route) -> bool {
|
2016-04-02 07:51:40 +00:00
|
|
|
if self.path.segment_count() != b.path.segment_count()
|
|
|
|
|| self.method != b.method {
|
2016-03-21 04:27:17 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.path.collides_with(&b.path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Collider<Route> for &'a str {
|
|
|
|
fn collides_with(&self, other: &Route) -> bool {
|
2016-04-02 07:51:40 +00:00
|
|
|
let path = URI::new(self);
|
2016-03-21 04:27:17 +00:00
|
|
|
path.collides_with(&other.path)
|
|
|
|
}
|
|
|
|
}
|
2016-03-21 09:22:22 +00:00
|
|
|
|
|
|
|
impl Collider<str> for Route {
|
|
|
|
fn collides_with(&self, other: &str) -> bool {
|
|
|
|
other.collides_with(self)
|
|
|
|
}
|
|
|
|
}
|