use crate::server::PreHandler; use argentum_rest_infrastructure::data_type::error::HttpError; use argentum_rest_infrastructure::data_type::{HttpResponse, Request}; use argentum_rest_infrastructure::service::{ErrorPreHandler, RouterTrait}; use async_trait::async_trait; use hyper::{Method, Uri}; use regex::Regex; use std::collections::HashMap; use std::sync::Arc; pub struct Router { pre_handler: Arc, error_pre_handler: Arc, url_prefix: String, } impl Router { pub fn new( pre_handler: Arc, error_pre_handler: Arc, url_prefix: String, ) -> Self { Self { pre_handler, error_pre_handler, url_prefix, } } } #[async_trait] impl RouterTrait for Router { fn is_route_supported(&self, uri: &Uri, method: &Method) -> bool { let path = uri.path(); let path = match path.strip_prefix(self.url_prefix.as_str()) { None => return false, Some(path) => path, }; {{#each paths as |path|}} if let Some(_) = Regex::new(r"{{{path.pattern}}}").unwrap().captures(path) { return match *method { {{#each path.operations }} {{@key}} => true, {{/each}} _ => false, }; } {{/each}} false } async fn route(&self, req: Request) -> Result { let path = req.uri().path(); let path = match path.strip_prefix(self.url_prefix.as_str()) { None => return self.error_pre_handler.route_not_found(req).await, Some(path) => path, }; {{#each paths as |path|}} if let Some({{#if params}}caps{{else}}_{{/if}}) = Regex::new(r"{{{path.pattern}}}").unwrap().captures(path) { {{#each params as |param|}} let {{ snake param.name }} = caps["{{ camel param.name }}"].to_string(); {{/each}} let raw_path_params = HashMap::from([ {{#each params as |param|}} ("{{ snake param.name }}", {{ snake param.name }}.as_str()), {{/each}} ]); return match *req.method() { {{#each path.operations }} {{@key}} => self.pre_handler.{{snake this.operationId}}(req, raw_path_params).await, {{/each}} _ => self.error_pre_handler.method_not_allowed(req).await, }; } {{/each}} self.error_pre_handler.route_not_found(req).await } }