#![allow(dead_code)]
pub(crate) mod client;
use crate::{cache::Cache, utils, RastAPI, Request, Response};
use regex;
use regex::Regex;
use std::{collections::HashMap, path::PathBuf, ptr::NonNull, time::Duration};
use utils::Method;
use Request::HttpRequest;
use Response::HttpResponse;
pub(crate) type RouteFunction = fn(&HttpRequest, HashMap<String, String>) -> HttpResponse;
#[derive(Debug)]
pub(crate) struct Route {
pub(crate) function: RouteFunction,
pub(crate) methods: Vec<Method>,
}
impl Route {
pub(crate) fn new(func: RouteFunction, mut methods: Vec<Method>) -> Self {
if methods.is_empty() {
methods.push(Method::GET);
}
Self {
function: func,
methods: methods,
}
}
}
pub(crate) struct URLRouter {
pub(crate) router: HashMap<String, Route>,
}
impl URLRouter {
pub(crate) fn new() -> Self {
Self {
router: HashMap::new(),
}
}
pub(crate) fn get_route(
&self,
url: &str,
path_params_opt: Option<&mut HashMap<String, String>>,
) -> Option<&Route> {
for (key, val) in self.router.iter() {
let re = Regex::new(key).unwrap();
if re.is_match(url) {
if let Some(path_params) = path_params_opt {
if let Some(captures) = re.captures(url) {
for name in re.capture_names().flatten() {
if let Some(val) = captures.name(name) {
path_params.insert(name.to_string(), val.as_str().to_string());
}
}
}
}
return Some(val);
}
}
None
}
pub(crate) fn add_route(&mut self, url: &str, route: Route) -> () {
let re = Regex::new(r#"\{([a-zA-Z0-9_]+)\}"#).unwrap();
let regex_pattern = re.replace_all(url, "(?P<$1>[ -~]+)").to_string();
let mut final_pattern = String::from("^");
final_pattern.push_str(®ex_pattern);
final_pattern.push('$');
let _res = self.router.insert(final_pattern, route);
}
pub(crate) fn remove_route(&mut self, url: &str) -> () {
let re = Regex::new(r#"\{([a-zA-Z0-9_]+)\}"#).unwrap();
let regex_pattern = re.replace_all(url, "(?P<$1>[ -~]+)").to_string();
let mut final_pattern = String::from("^");
final_pattern.push_str(®ex_pattern);
final_pattern.push('$');
self.router.remove(&final_pattern);
}
}
pub(crate) struct AppEnv {
pub host: String,
pub port: u16,
pub cache: NonNull<Cache<PathBuf>>,
pub routes: NonNull<URLRouter>,
pub maximum_pay_load_in_bytes: usize,
pub read_time_out: Duration,
pub write_time_out: Duration,
pub keep_alive_time_out: Duration,
pub keep_alive_max_count: u8,
pub incoming_file_directory: String,
pub send_buffer_size:usize
}
impl AppEnv {
pub fn new(host: &str, port: u16, app: &RastAPI,send_buf_size:usize) -> Self {
Self {
host: host.to_string(),
port,
cache: app.cache,
routes: app.routes,
maximum_pay_load_in_bytes: app.payload_maximum_size_in_MB * 1024 * 1024,
read_time_out: app.read_time_out,
write_time_out: app.write_time_out,
keep_alive_time_out: app.keep_alive_time_out,
keep_alive_max_count: app.keep_alive_max_count,
incoming_file_directory: app.file_upload_directory_name.clone(),
send_buffer_size:send_buf_size
}
}
}
unsafe impl Send for AppEnv {}
unsafe impl Sync for AppEnv {}