use std::{collections::HashMap}; use async_trait::async_trait; use hyper::{Body, Method}; use crate::{Request, config::{RegexPath, Route}}; #[async_trait] pub trait Router: RouterClone + Send { async fn route(&self, path: &str, request: Request, body: Option, bundle: B) -> (Request, Option, B, Option>>); } pub trait RouterClone { fn clone_box(&self) -> Box>; } impl RouterClone for T where T: 'static + Router + Clone { fn clone_box(&self) -> Box> { Box::new(self.clone()) } } impl Clone for Box> { fn clone(&self) -> Box> { self.clone_box() } } #[async_trait] impl Router for HashMap<&'static str, HashMap>> { async fn route(&self, path: &str, request: Request, body: Option, bundle: B) -> (Request, Option, B, Option>>) { let methods = match self.get(path) { None => None, Some(methods) => Some(methods.clone()) }; (request, body, bundle, methods) } } #[async_trait] impl Router for Vec> { async fn route(&self, path: &str, request: Request, body: Option, bundle: B) -> (Request, Option, B, Option>>) { for regex_path_route in self { if let Some(path_captures) = regex_path_route.regex.captures(path) { let mut path_params = vec![]; for i in 1..path_captures.len() { path_params.push(path_captures.get(i).unwrap().as_str().to_string()); } let request = Request { id: request.id, head: request.head, remote_addr: request.remote_addr, path_params, shutdown_tx: request.shutdown_tx, }; let methods = Some(regex_path_route.routes.clone()); return (request, body, bundle, methods) } } (request, body, bundle, None) } }