tosic_http/
resource.rs

1//! RouteBuilder is a builder pattern for creating routes for an [`HttpServer`].
2
3use crate::body::BoxBody;
4use crate::error::Error;
5use crate::handlers::Handlers;
6use crate::prelude::{FromRequest, Handler, Responder};
7use http::Method;
8use paste::paste;
9use std::borrow::Cow;
10use std::future::Future;
11
12#[allow(unused_imports)]
13use crate::prelude::HttpServer;
14
15/// RouteBuilder is a builder pattern for creating routes for an [`HttpServer`].
16pub struct RouteBuilder<'a> {
17    path: Cow<'a, str>,
18    handlers: Handlers,
19}
20
21macro_rules! route_method (
22    {$($method:ident),+} => {
23        $(
24            paste! {
25                /// Add a handler for the given method
26                pub fn $method<H, Args>(self, handler: H) -> Self
27                where
28                    H: Handler<Args> + Send + Sync + 'static,
29                    Args: FromRequest + Send + 'static,
30                    Args::Future: Future + Send + 'static,
31                    H::Future: Future + Send + 'static,
32                    H::Output: Responder<Body= BoxBody> + 'static,
33                    Error: From<Args::Error>,
34                {
35                    self.insert_handler(Method::[<$method:snake:upper>], handler)
36                }
37            }
38        )+
39    };
40);
41
42macro_rules! route_function (
43    {$($method:ident),+} => {
44        $(
45            paste! {
46                /// Create a new [`RouteBuilder`] for the given method and add a handler
47                pub fn $method<H, Args>(path: &str, handler: H) -> RouteBuilder<'_>
48                where
49                    H: Handler<Args> + Send + Sync + 'static,
50                    Args: FromRequest + Send + 'static,
51                    Args::Future: Future + Send + 'static,
52                    H::Future: Future + Send + 'static,
53                    H::Output: Responder<Body= BoxBody> + 'static,
54                    Error: From<Args::Error>,
55                {
56                    RouteBuilder::new(path).insert_handler(Method::[<$method:snake:upper>], handler)
57                }
58            }
59        )+
60    };
61);
62
63impl<'a> RouteBuilder<'a> {
64    /// Create a new [`RouteBuilder`]
65    pub(crate) fn new(path: &'a str) -> Self {
66        Self {
67            path: path.into(),
68            handlers: Handlers::new(),
69        }
70    }
71
72    /// Add a handler for the given method
73    pub fn insert_handler<H, Args>(mut self, method: Method, handler: H) -> Self
74    where
75        H: Handler<Args> + Send + Sync + 'static,
76        Args: FromRequest + Send + 'static,
77        Args::Future: Future + Send + 'static,
78        H::Future: Future + Send + 'static,
79        H::Output: Responder<Body = BoxBody> + 'static,
80        Error: From<Args::Error>,
81    {
82        if self.handlers.contains_key(&method) {
83            panic!("You cant have more than one handler per method!")
84        }
85
86        self.handlers.insert(method, &self.path, handler);
87
88        self
89    }
90
91    /// Get the handlers
92    pub(crate) fn handlers(self) -> Handlers {
93        self.handlers
94    }
95
96    route_method! {get, post, put, delete, trace, options, head, connect, patch}
97}
98
99route_function! {get, post, put, delete, trace, options, head, connect, patch}