1use std::collections::HashMap;
2use std::sync::Mutex;
3use inventory::iter;
4
5use crate::provider::{get_service_provider, ServiceProvider};
6
7#[derive(Clone)]
8pub struct Route {
9 pub method: String,
10 pub path: String,
11 pub handler: fn(String) -> String,
12 pub has_body: bool,
13}
14
15inventory::collect!(Route);
16
17pub struct WebHost {
18 provider: &'static Mutex<ServiceProvider>,
19 routes: HashMap<String, Route>,
20}
21
22impl WebHost {
23 pub fn new<T: IStartup + 'static>() -> Self {
24 let provider = get_service_provider();
25
26 {
27 let mut sp = provider.lock().unwrap();
28 T::configure_services(&mut sp);
29 }
30
31 let mut web_host = WebHost {
32 provider,
33 routes: HashMap::new(),
34 };
35
36 web_host.add_controllers();
37 web_host
38 }
39
40 pub fn add_controllers(&mut self) {
41 for route in iter::<Route> {
42 let key = format!("{}:{}", route.method, route.path);
43 self.routes.insert(key, route.clone());
44 }
45 }
46
47 pub fn handle_request(&self, method: &str, path: &str, body: Option<String>) -> Option<String> {
48 let key = format!("{}:{}", method, path);
49 if let Some(route) = self.routes.get(&key) {
50 return Some((route.handler)(path.to_string()));
51 }
52 None
53 }
54
55 pub fn start(&self) {
56 let routes = self.routes.clone(); std::thread::spawn(move || {
58 for (key, route) in &routes {
60 let response = (route.handler)("".to_string());
61 println!("Handled {}: {}", key, response);
62 }
63 }).join().unwrap();
64 }
65}
66
67pub trait IStartup {
68 fn configure_services(provider: &mut ServiceProvider);
69}