diff --git a/src/api/router.rs b/src/api/router.rs new file mode 100644 index 00000000..d0e475da --- /dev/null +++ b/src/api/router.rs @@ -0,0 +1,91 @@ +use failure::*; + +use crate::api::schema::*; +use serde_json::{Value}; +use std::collections::HashMap; + +pub struct ApiMethod { + pub description: &'static str, + pub parameters: Schema, + pub returns: Schema, + pub handler: fn(Value, &ApiMethod) -> Result, +} + +pub enum SubRoute { + None, + Hash(HashMap), + MatchAll { router: Box, param_name: String }, +} + +pub struct Router { + pub get: Option, + pub put: Option, + pub post: Option, + pub delete: Option, + pub subroute: SubRoute, +} + +impl Router { + + pub fn new() -> Self { + Self { + get: None, + put: None, + post: None, + delete: None, + subroute: SubRoute::None + } + } + + pub fn subdirs(mut self, map: HashMap) -> Self { + self.subroute = SubRoute::Hash(map); + self + } + + pub fn match_all(mut self, router: Router) -> Self { + self.subroute = SubRoute::MatchAll { router: Box::new(router), param_name: "test".into() }; + self + } + + pub fn get(mut self, m: ApiMethod) -> Self { + self.get = Some(m); + self + } + + pub fn find_route(&self, components: &[&str]) -> Option<&Router> { + + if components.len() == 0 { return Some(self); }; + + let (dir, rest) = (components[0], &components[1..]); + + match self.subroute { + SubRoute::None => {}, + SubRoute::Hash(ref dirmap) => { + if let Some(ref router) = dirmap.get(dir) { + println!("FOUND SUBDIR {}", dir); + return router.find_route(rest); + } + } + SubRoute::MatchAll { ref router, ref param_name } => { + println!("URI PARAM {} = {}", param_name, dir); // fixme: store somewhere + return router.find_route(rest); + }, + } + + None + } +} + +// fixme: remove - not required? +#[macro_export] +macro_rules! methodinfo { + ($($option:ident => $e:expr),*) => {{ + let info = Router::new(); + + $( + info.$option = Some($e); + )* + + info + }} +}