tosic_http/route/
node.rs

1//! Routes and handlers are stored in a tree structure.
2
3use crate::body::BoxBody;
4use crate::error::Error;
5use crate::request::{HttpPayload, HttpRequest};
6use crate::response::HttpResponse;
7use std::borrow::Cow;
8use std::collections::{BTreeMap, HashMap};
9use std::fmt::Debug;
10use std::future::Future;
11use std::ops::{Deref, DerefMut};
12use std::pin::Pin;
13use std::sync::Arc;
14use std::task::{Context, Poll};
15use tower::Service;
16//use crate::handlers::HandlerType;
17use super::{PathSegment, Route};
18use crate::traits::from_request::FromRequest;
19use crate::traits::handler::Handler;
20use crate::traits::responder::Responder;
21
22#[derive(Clone)]
23/// [`HandlerFn`] is a wrapper around a handler function so that it can be used as a [`Service`].
24pub struct HandlerFn(Arc<HandlerInner>);
25
26impl HandlerFn {
27    /// Create a new handler function from a handler
28    pub(crate) fn wrap<H, Args>(handler: H) -> HandlerFn
29    where
30        H: Handler<Args> + Send + Sync + 'static,
31        Args: FromRequest + Send + 'static,
32        Args::Future: Future + Send + 'static,
33        H::Future: Future + Send + 'static,
34        H::Output: Responder<Body = BoxBody> + 'static,
35        Error: From<Args::Error>,
36    {
37        Self(wrap_handler_fn(Arc::new(handler)))
38    }
39}
40
41impl Deref for HandlerFn {
42    type Target = Arc<HandlerInner>;
43
44    #[inline]
45    fn deref(&self) -> &Self::Target {
46        &self.0
47    }
48}
49
50impl DerefMut for HandlerFn {
51    #[inline]
52    fn deref_mut(&mut self) -> &mut Self::Target {
53        &mut self.0
54    }
55}
56
57/// The inner type of [`HandlerFn`].
58pub(crate) type HandlerInner = dyn Fn(
59        HttpRequest,
60        &mut HttpPayload,
61    ) -> Pin<Box<dyn Future<Output = Result<HttpResponse, Error>> + Send>>
62    + Send
63    + Sync;
64
65impl Service<(HttpRequest, HttpPayload)> for HandlerFn {
66    type Response = HttpResponse;
67    type Error = Error;
68    type Future = Pin<Box<dyn Future<Output = Result<HttpResponse, Error>> + Send>>;
69
70    #[inline]
71    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
72        Poll::Ready(Ok(()))
73    }
74
75    #[inline]
76    fn call(&mut self, mut req: (HttpRequest, HttpPayload)) -> Self::Future {
77        self.0(req.0, &mut req.1)
78    }
79}
80
81unsafe impl Send for HttpPayload {}
82unsafe impl Send for BoxBody {}
83
84/// Wrap a handler function so that it can be used as a [`Service`].
85pub(crate) fn wrap_handler_fn<H, Args>(handler: Arc<H>) -> Arc<HandlerInner>
86where
87    H: Handler<Args> + Send + Sync + 'static,
88    Args: FromRequest + Send + 'static,
89    Args::Future: Future + Send + 'static,
90    H::Future: Future + Send + 'static,
91    H::Output: Responder<Body = BoxBody> + 'static,
92    Error: From<Args::Error>,
93{
94    Arc::new(
95        #[inline]
96        move |req: HttpRequest,
97              payload: &mut HttpPayload|
98              -> Pin<Box<dyn Future<Output = Result<HttpResponse, Error>> + Send>> {
99            let handler = handler.clone();
100            let req = req;
101
102            let mut payload = payload.clone();
103
104            Box::pin(async move {
105                let args = Args::from_request(&req, &mut payload).await?;
106                let res = handler.call(args).await;
107
108                Ok(res.respond_to(&req))
109            })
110        },
111    ) as Arc<HandlerInner>
112}
113
114#[derive(Clone)]
115/// A tree of routes.
116///
117/// It supports static, parameter, and wildcard routes.
118///
119/// ## Syntax
120///
121/// - `/` -> static route
122/// - `/a/b` -> static route
123/// - `/{param}/a` -> parameter as the first segment
124/// - `/a/*/b` -> wildcard in the middle
125/// - `/a/**` -> deep wildcard
126pub struct RouteNode {
127    static_children: HashMap<Cow<'static, str>, RouteNode>,
128    parameter_child: Option<(Cow<'static, str>, Box<RouteNode>)>,
129    wildcard_child: Option<Box<RouteNode>>,
130    handler: Option<HandlerFn>,
131}
132
133impl Debug for RouteNode {
134    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135        #[derive(Debug)]
136        enum DebugHandler {
137            Some,
138            None,
139        }
140
141        let mut binding = f.debug_struct("RouteNode");
142        let f = binding
143            .field("static_children", &self.static_children)
144            .field("parameter_child", &self.parameter_child)
145            .field("wildcard_child", &self.wildcard_child);
146
147        let f = if self.handler.is_some() {
148            f.field("handler", &DebugHandler::Some)
149        } else {
150            f.field("handler", &DebugHandler::None)
151        };
152
153        f.finish()
154    }
155}
156
157impl Default for RouteNode {
158    fn default() -> Self {
159        Self::new()
160    }
161}
162
163impl RouteNode {
164    /// Creates a new empty route node.
165    pub fn new() -> Self {
166        RouteNode {
167            static_children: HashMap::new(),
168            parameter_child: None,
169            wildcard_child: None,
170            handler: None,
171        }
172    }
173
174    /// Extends the current route node with another route node.
175    pub fn extend(&mut self, other: RouteNode) {
176        for (key, other_child) in other.static_children {
177            if let Some(child) = self.static_children.get_mut(&key) {
178                child.extend(other_child);
179            } else {
180                self.static_children.insert(key, other_child);
181            }
182        }
183
184        if let Some((other_param_name, other_child)) = other.parameter_child {
185            if let Some((_param_name, child)) = &mut self.parameter_child {
186                child.extend(*other_child);
187            } else {
188                self.parameter_child = Some((other_param_name, other_child));
189            }
190        }
191
192        if let Some(other_child) = other.wildcard_child {
193            if let Some(child) = &mut self.wildcard_child {
194                child.extend(*other_child);
195            } else {
196                self.wildcard_child = Some(other_child);
197            }
198        }
199
200        if other.handler.is_some() {
201            self.handler = other.handler;
202        }
203    }
204
205    /// Inserts a handler into the route node.
206    pub fn insert<H, Args>(&mut self, route: &Route, handler: H)
207    where
208        H: Handler<Args> + Send + Sync + 'static,
209        Args: FromRequest + Send + 'static,
210        Args::Future: Future + Send + 'static,
211        H::Future: Future + Send + 'static,
212        H::Output: Responder<Body = BoxBody> + 'static,
213        Error: From<Args::Error>,
214    {
215        let handler_fn = HandlerFn::wrap(handler);
216
217        self.insert_segments(route.segments(), handler_fn);
218    }
219
220    /// Inserts individual segments into the route node.
221    fn insert_segments(&mut self, segments: &[PathSegment], handler: HandlerFn) {
222        if segments.is_empty() {
223            self.handler = Some(handler);
224            return;
225        }
226
227        match &segments[0] {
228            PathSegment::Static(segment) => {
229                let child = self.static_children.entry(segment.clone()).or_default();
230                child.insert_segments(&segments[1..], handler);
231            }
232            PathSegment::Parameter(param_name) => {
233                if self.parameter_child.is_none() {
234                    self.parameter_child = Some((param_name.clone(), Box::new(RouteNode::new())));
235                }
236
237                let (_, child_node) = self.parameter_child.as_mut().unwrap();
238                child_node.insert_segments(&segments[1..], handler);
239            }
240            PathSegment::Wildcard => {
241                if self.wildcard_child.is_none() {
242                    self.wildcard_child = Some(Box::new(RouteNode::new()));
243                }
244
245                let child_node = self.wildcard_child.as_mut().unwrap();
246                child_node.insert_segments(&segments[1..], handler);
247            }
248            PathSegment::WildcardDeep => {
249                if self.wildcard_child.is_none() {
250                    self.wildcard_child = Some(Box::new(RouteNode::new()));
251                }
252
253                let child_node = self.wildcard_child.as_mut().unwrap();
254                // WildcardDeep means this node should handle all remaining segments
255                child_node.handler = Some(handler.clone());
256            }
257        }
258    }
259
260    /// Matches a path against the route node.
261    pub fn match_path(&self, route: &Route) -> Option<(HandlerFn, BTreeMap<String, String>)> {
262        self.match_segments(route.segments())
263    }
264
265    /// Matches segments against the route node.
266    pub fn match_segments(
267        &self,
268        segments: &[PathSegment],
269    ) -> Option<(HandlerFn, BTreeMap<String, String>)> {
270        if segments.is_empty() {
271            return self
272                .handler
273                .clone()
274                .map(|handler| (handler, BTreeMap::new()));
275        }
276
277        if let PathSegment::Static(segment) = &segments[0] {
278            if let Some(child) = self.static_children.get(segment) {
279                if let Some((handler, params)) = child.match_segments(&segments[1..]) {
280                    return Some((handler, params));
281                }
282            }
283        }
284
285        if let Some((param_name, child)) = &self.parameter_child {
286            if let Some((handler, mut params)) = child.match_segments(&segments[1..]) {
287                if let PathSegment::Static(value) = &segments[0] {
288                    params.insert(param_name.to_string(), value.to_string());
289                }
290                return Some((handler, params));
291            }
292        }
293
294        if let Some(child) = &self.wildcard_child {
295            return if let Some((handler, params)) = child.match_segments(&segments[1..]) {
296                Some((handler, params))
297            } else if let Some(_handler) = &child.handler {
298                let remaining: Vec<_> = segments.to_vec();
299                let mut params = BTreeMap::new();
300                params.insert(
301                    "wildcard_deep".to_string(),
302                    remaining
303                        .iter()
304                        .map(|segment| format!("{}", segment))
305                        .collect::<Vec<_>>()
306                        .join("/"),
307                );
308                Some((child.handler.clone()?, params))
309            } else {
310                None
311            };
312        }
313
314        None
315    }
316}