1use crate::{
2 routes::{RequestProcessor, RouteContext, RouteMethod},
3 server::Server,
4};
5use serde::{Serialize, de::DeserializeOwned};
6use serde_json::Value;
7use std::{collections::HashMap, error::Error, net::SocketAddr};
8
9pub struct Request(pub http::Request<Value>);
10pub struct Response(pub http::Response<Value>);
11
12pub trait Route: FnMut(Request) -> Response + 'static {}
14impl<T> Route for T where T: FnMut(Request) -> Response + 'static {}
15
16pub trait TextRoute: FnMut() -> String + 'static {}
22impl<T> TextRoute for T where T: FnMut() -> String + 'static {}
23
24#[derive(Default)]
43pub struct Mise {
44 routes: HashMap<RouteMethod, HashMap<String, RouteContext>>,
45 text_routes: HashMap<String, Box<dyn TextRoute>>,
46}
47
48impl Mise {
49 pub fn new() -> Self {
51 Self::default()
52 }
53
54 pub fn text<F: TextRoute>(mut self, path: &str, f: F) -> Self {
59 self.text_routes.insert(path.to_string(), Box::new(f));
60 self
61 }
62
63 pub fn get<F: Route>(mut self, path: &str, f: F) -> Self {
65 self.regiser_method(RouteMethod::Get, path, f);
66 self
67 }
68
69 pub fn delete<F: Route>(mut self, path: &str, f: F) -> Self {
71 self.regiser_method(RouteMethod::Delete, path, f);
72 self
73 }
74
75 pub fn post<F: Route>(mut self, path: &str, f: F) -> Self {
78 self.regiser_method(RouteMethod::Post, path, f);
79 self
80 }
81
82 pub fn put<F: Route>(mut self, path: &str, f: F) -> Self {
85 self.regiser_method(RouteMethod::Put, path, f);
86 self
87 }
88
89 pub fn patch<F: Route>(mut self, path: &str, f: F) -> Self {
92 self.regiser_method(RouteMethod::Patch, path, f);
93 self
94 }
95
96 pub fn serve(self, addr: SocketAddr) {
99 Server::serve(
100 RequestProcessor {
101 routes: self.routes,
102 text_routes: self.text_routes,
103 },
104 addr,
105 )
106 .run();
107 }
108
109 fn regiser_method<F: Route>(&mut self, method: RouteMethod, path: &str, f: F) {
110 let routes = self.routes.entry(method).or_default();
111 let d: Box<dyn Route> = Box::new(f);
112 routes.insert(path.to_string(), (path, d).into());
113 }
114}
115
116impl From<Request> for Value {
117 fn from(value: Request) -> Self {
118 value.0.body().to_owned()
119 }
120}
121
122impl From<Value> for Response {
123 fn from(value: Value) -> Self {
124 Response(http::Response::new(value))
125 }
126}
127
128impl From<http::StatusCode> for Response {
129 fn from(value: http::StatusCode) -> Self {
130 Response(
131 http::Response::builder()
132 .status(value)
133 .body(Value::Null)
134 .expect("Statically built body should not fail"),
135 )
136 }
137}
138
139pub trait Serializable: Serialize {
140 fn to_response(&self) -> Result<Response, Box<dyn Error>> {
141 Ok(Response(http::Response::new(serde_json::to_value(self)?)))
142 }
143}
144impl<T> Serializable for T where T: Serialize {}
145
146pub trait Deserializable: DeserializeOwned {
147 fn from_request(r: Request) -> Result<Self, Box<dyn Error>> {
148 Ok(serde_json::from_value(r.body().to_owned())?)
149 }
150}
151impl<T> Deserializable for T where T: DeserializeOwned {}
152
153impl Request {
154 pub fn path(&self) -> &str {
156 self.0.uri().path()
157 }
158
159 pub fn query(&self) -> Option<&str> {
160 self.0.uri().query()
161 }
162
163 pub fn query_param(&self, name: &str) -> Option<&str> {
165 let q = self.0.uri().query()?;
166 let f = format!("{name}=");
167 let idx = q.find(&f)?;
168 let end = q[idx..].find('&').unwrap_or(q.len());
169 Some(&q[idx + f.len()..end])
170 }
171
172 pub fn base(&self) -> &str {
178 let p = self.0.uri().path();
179 let n = self.name();
180 p[..p.len() - n.len()].trim_end_matches("/")
181 }
182
183 pub fn name(&self) -> &str {
189 if !self.0.uri().path().contains("/") {
190 return "";
191 }
192 self.0.uri().path().split("/").last().unwrap_or("")
193 }
194
195 pub fn body(&self) -> &Value {
199 self.0.body()
200 }
201
202 pub(crate) fn base_star(&self) -> Option<String> {
203 if self.name().is_empty() {
204 return None;
206 }
207 Some(format!("{}/*", self.base()))
208 }
209}
210
211#[cfg(test)]
212mod test {
213 use super::*;
214 use serde::Deserialize;
215 use serde_json::json;
216
217 #[derive(Serialize, Deserialize)]
218 struct My {
219 val: usize,
220 }
221
222 #[test]
223 fn test_serde() {
224 let m = My { val: 1 };
225 let r = m.to_response().unwrap();
226 assert_eq!(r.0.body()["val"].clone(), 1);
227
228 let r = Request(http::Request::new(json!({"val":2})));
229 let m = My::from_request(r).unwrap();
230 assert_eq!(m.val, 2);
231 }
232
233 #[test]
234 fn test_paths() {
235 assert_eq!(requri("/").name(), "");
236 assert_eq!(requri("/a").name(), "a");
237 assert_eq!(requri("/a/b").name(), "b");
238
239 assert_eq!(requri("/").base(), "");
240 assert_eq!(requri("/a").base(), "");
241 assert_eq!(requri("/a/b").base(), "/a");
242
243 assert_eq!(requri("/").base_star(), None);
244 assert_eq!(requri("/a").base_star(), Some("/*".to_string()));
245 assert_eq!(requri("/a/b").base_star(), Some("/a/*".to_string()));
246
247 assert_eq!(requri("/?b=a").query_param("b"), Some("a"));
248 }
249
250 fn requri(uri: &str) -> Request {
251 Request(http::Request::builder().uri(uri).body(Value::Null).unwrap())
252 }
253}