1use std::future::Future;
2use std::pin::Pin;
3use std::sync::Arc;
4
5use async_trait::async_trait;
6use http::Method;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum HttpMethod {
11 Get,
12 Post,
13 Put,
14 Patch,
15 Delete,
16 Options,
17 Head,
18}
19
20impl From<HttpMethod> for Method {
21 fn from(value: HttpMethod) -> Self {
22 match value {
23 HttpMethod::Get => Method::GET,
24 HttpMethod::Post => Method::POST,
25 HttpMethod::Put => Method::PUT,
26 HttpMethod::Patch => Method::PATCH,
27 HttpMethod::Delete => Method::DELETE,
28 HttpMethod::Options => Method::OPTIONS,
29 HttpMethod::Head => Method::HEAD,
30 }
31 }
32}
33
34#[derive(Clone)]
36pub struct RouteDefinition {
37 pub method: HttpMethod,
38 pub path: String,
39 pub handler_name: &'static str,
40 pub handler: Arc<dyn RouteHandler>,
41}
42
43#[async_trait]
45pub trait RouteHandler: Send + Sync {
46 async fn handle(&self, request: axum::extract::Request) -> axum::response::Response;
47}
48
49pub type HandlerFuture =
51 Pin<Box<dyn Future<Output = axum::response::Response> + Send>>;
52
53pub fn boxed_handler<F, Fut>(f: F) -> Arc<dyn RouteHandler>
54where
55 F: Fn(axum::extract::Request) -> Fut + Send + Sync + 'static,
56 Fut: Future<Output = axum::response::Response> + Send + 'static,
57{
58 struct FnHandler<F>(F);
59
60 #[async_trait]
61 impl<F, Fut> RouteHandler for FnHandler<F>
62 where
63 F: Fn(axum::extract::Request) -> Fut + Send + Sync,
64 Fut: Future<Output = axum::response::Response> + Send,
65 {
66 async fn handle(&self, request: axum::extract::Request) -> axum::response::Response {
67 (self.0)(request).await
68 }
69 }
70
71 Arc::new(FnHandler(f))
72}