1use std::fmt::{self, Debug};
2use std::rc::Rc;
3use std::sync::Arc;
4
5use crate::{path::Path, Method, Request, Response};
6
7type StatelessRoute = Box<dyn Fn(&Request) -> Response + Send + Sync>;
8type StatefulRoute<State> = Box<dyn Fn(Arc<State>, &Request) -> Response + Send + Sync>;
9
10pub enum RouteType<State> {
11 Stateless(StatelessRoute),
12 Stateful(StatefulRoute<State>),
13}
14
15#[derive(Debug)]
20pub struct Route<State> {
21 method: Method,
23
24 path: Path,
26
27 pub(crate) handler: RouteType<State>,
29}
30
31impl<State> Route<State> {
32 pub(crate) fn new(method: Method, path: String, handler: StatelessRoute) -> Self {
34 Self {
35 method,
36 path: Path::new(path),
37 handler: RouteType::Stateless(handler),
38 }
39 }
40
41 pub(crate) fn new_stateful(
43 method: Method,
44 path: String,
45 handler: StatefulRoute<State>,
46 ) -> Self {
47 Self {
48 method,
49 path: Path::new(path),
50 handler: RouteType::Stateful(handler),
51 }
52 }
53
54 pub(crate) fn is_stateful(&self) -> bool {
56 matches!(self.handler, RouteType::Stateful(_))
57 }
58
59 pub(crate) fn matches(&self, req: Rc<Request>) -> Option<Vec<(String, String)>> {
62 if self.method != Method::ANY && self.method != req.method {
63 return None;
64 }
65 self.path.match_path(req.path.clone())
66 }
67}
68
69impl<State> Debug for RouteType<State> {
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 match self {
72 RouteType::Stateless(_) => f.write_str("stateless"),
73 RouteType::Stateful(_) => f.write_str("stateful"),
74 }
75 }
76}