1use crate::context::Context;
2use crate::middleware::Middleware;
3use crate::types::HttpResonse;
4use crate::view::View;
5use hyper::service::{make_service_fn, service_fn};
6use hyper::{Server, StatusCode};
7use once_cell::sync::Lazy;
8use route::match_view;
9use std::borrow::BorrowMut;
10
11use std::convert::Infallible;
12use std::net::SocketAddr;
13use std::sync::Arc;
14use tokio::sync::Mutex;
15use types::{State, HttpRequest};
16use std::any;
17
18pub mod context;
19pub mod middleware;
20pub mod middlewares;
21pub mod views;
22pub mod response;
23pub mod route;
24pub mod session;
25pub mod types;
26pub mod utils;
27pub mod view;
28
29pub static GLOBAL_SIMPLE_API_INSTANCE: Lazy<SimpleApi> = Lazy::new(|| SimpleApi::new());
30
31pub async fn apply_middlewares_pre(
32 req: &mut HttpRequest,
33 ctx: &mut Context,
34 middlewares: &Vec<Arc<dyn Middleware>>,
35) -> anyhow::Result<Option<HttpResonse>> {
36 for m in middlewares.iter() {
37 match m.pre_process(req, ctx).await {
38 Ok(None) => continue,
39 other => return other,
40 }
41 }
42 Ok(None)
43}
44
45pub async fn apply_middlewares_post(
46 req: &mut HttpRequest,
47 res: &mut HttpResonse,
48 ctx: &mut Context,
49 middlewares: &Vec<Arc<dyn Middleware>>,
50) -> anyhow::Result<Option<HttpResonse>> {
51 for m in middlewares.iter() {
52 match m.post_process(req, res, ctx).await {
53 Ok(None) => continue,
54 other => return other,
55 }
56 }
57 Ok(None)
58}
59
60async fn app_core(mut req: HttpRequest) -> Result<HttpResonse, Infallible> {
61 let path = req.uri().path().to_string();
62 let (view, mut ctx) = {
63 let view_and_vpas = {
64 let _routes = SimpleApi::routes();
65 let _routes = _routes.lock().await;
66
67 match_view(&_routes, &path)
68 };
69 let (view, view_args) = match view_and_vpas {
70 Some(v) => (Some(v.0), Some(v.1)),
71 None => (None, None),
72 };
73
74 let sp = SimpleApi::session_provider().lock().await.clone();
75
76 let state = SimpleApi::state().lock().await.clone();
77
78 let ctx = Context::new(sp, state, view_args);
79 (view, ctx)
80 };
81
82 let middlewares = SimpleApi::middlewares();
83 match apply_middlewares_pre(&mut req, &mut ctx, &middlewares.lock().await.borrow_mut()).await {
84 Ok(None) => (),
85 Ok(Some(v)) => return Ok(v),
86 Err(e) => return Ok(response::internal_server_error(e).unwrap()),
87 }
88
89 let Some(view) = view else {
90 return Ok(response::build_response(
91 format!("Not found: {}", path),
92 StatusCode::NOT_FOUND,
93 "text/html",
94 )
95 .unwrap());
96 };
97
98 match view.call(&mut req, &mut ctx).await {
99 Ok(r) => {
100 let mut res = r;
101 match apply_middlewares_post(
102 &mut req,
103 &mut res,
104 &mut ctx,
105 &middlewares.lock().await.borrow_mut(),
106 )
107 .await
108 {
109 Ok(None) => (),
110 Ok(Some(v)) => return Ok(v),
111 Err(e) => return Ok(response::internal_server_error(e).unwrap()),
112 }
113 Ok(res)
114 }
115 Err(e) => Ok(response::internal_server_error(e).unwrap()),
116 }
117}
118
119pub struct SimpleApi {
120 routes: Arc<Mutex<Vec<Arc<dyn View>>>>,
121 middlewares: Arc<Mutex<Vec<Arc<dyn Middleware>>>>,
122 session_provider: Arc<Mutex<Option<Arc<dyn session::SessionProvider>>>>,
123 state: Arc<Mutex<State>>,
124}
125
126impl SimpleApi {
127 pub fn new() -> Self {
128 let _middlewares: Vec<Arc<dyn Middleware>> = vec![Arc::new(middlewares::SessionMiddleware)];
129 SimpleApi {
130 routes: Arc::new(Mutex::new(Vec::new())),
131 middlewares: Arc::new(Mutex::new(_middlewares)),
132 session_provider: Arc::new(Mutex::new(None)),
133 state: Arc::new(Mutex::new(Arc::new(()))),
134 }
135 }
136
137 pub fn instance() -> &'static SimpleApi {
138 &GLOBAL_SIMPLE_API_INSTANCE
139 }
140
141 pub fn routes() -> Arc<Mutex<Vec<Arc<dyn View>>>> {
142 Self::instance().routes.clone()
143 }
144
145 pub fn middlewares() -> Arc<Mutex<Vec<Arc<dyn Middleware>>>> {
146 Self::instance().middlewares.clone()
147 }
148
149 pub fn session_provider() -> Arc<Mutex<Option<Arc<dyn session::SessionProvider>>>> {
150 Self::instance().session_provider.clone()
151 }
152
153 pub fn state() -> Arc<Mutex<State>> {
154 Self::instance().state.clone()
155 }
156
157 pub async fn add_route<T: any::Any + View>(view: T) {
158 let routes = SimpleApi::routes();
159 let mut routes = routes.lock().await;
160 routes.push(Arc::new(view));
161 }
162
163 pub async fn run(addr: &str) -> () {
164 let addr = addr.parse::<SocketAddr>().unwrap();
165
166 let make_svc = make_service_fn(|_conn| async {
167 Ok::<_, Infallible>(service_fn(app_core))
169 });
170
171 let server = Server::bind(&addr).serve(make_svc);
172
173 if let Err(e) = server.await {
175 eprintln!("server error: {}", e);
176 }
177 }
178
179 pub async fn add_middleware(m: Arc<dyn Middleware>) {
180 let middlewares = SimpleApi::middlewares();
181 let mut middlewares = middlewares.lock().await;
182 middlewares.push(m);
183 }
184
185 pub async fn set_session_provider(provider: Arc<dyn session::SessionProvider>) {
186 let sp = SimpleApi::session_provider();
187 let mut session_provider = sp.lock().await;
188 *session_provider = Some(provider);
189 }
190
191 pub async fn set_state(state: State) {
192 let s = SimpleApi::state();
193 let mut s = s.lock().await;
194 *s = state;
195 }
196}