Skip to main content

ntex_router/
lib.rs

1#![deny(clippy::pedantic)]
2#![allow(
3    clippy::must_use_candidate,
4    clippy::missing_panics_doc,
5    clippy::missing_errors_doc,
6    clippy::iter_without_into_iter,
7    clippy::cast_possible_wrap,
8    clippy::cast_sign_loss,
9    clippy::cast_possible_truncation,
10    clippy::too_many_lines
11)]
12
13//! Resource path matching library.
14mod de;
15mod path;
16mod resource;
17mod router;
18mod tree;
19
20pub use self::de::PathDeserializer;
21pub use self::path::{Path, PathIter};
22pub use self::resource::ResourceDef;
23pub use self::router::{ResourceId, Router, RouterBuilder};
24
25#[doc(hidden)]
26#[derive(Debug)]
27pub struct ResourceInfo;
28
29pub trait Resource<T: ResourcePath> {
30    fn path(&self) -> &str;
31
32    fn resource_path(&mut self) -> &mut Path<T>;
33}
34
35pub trait ResourcePath {
36    fn path(&self) -> &str;
37
38    fn unquote(s: &str) -> std::borrow::Cow<'_, str> {
39        s.into()
40    }
41}
42
43impl ResourcePath for String {
44    fn path(&self) -> &str {
45        self.as_str()
46    }
47}
48
49impl ResourcePath for &str {
50    fn path(&self) -> &str {
51        self
52    }
53}
54
55impl ResourcePath for ntex_bytes::ByteString {
56    fn path(&self) -> &str {
57        self
58    }
59}
60
61impl<T: ResourcePath> ResourcePath for &T {
62    fn path(&self) -> &str {
63        (*self).path()
64    }
65}
66
67/// Helper trait for type that could be converted to path pattern
68pub trait IntoPattern {
69    fn patterns(&self) -> Vec<String>;
70}
71
72impl IntoPattern for String {
73    fn patterns(&self) -> Vec<String> {
74        vec![self.clone()]
75    }
76}
77
78impl IntoPattern for &String {
79    fn patterns(&self) -> Vec<String> {
80        vec![self.as_str().to_string()]
81    }
82}
83
84impl IntoPattern for &str {
85    fn patterns(&self) -> Vec<String> {
86        vec![(*self).to_string()]
87    }
88}
89
90impl<T: AsRef<str>> IntoPattern for Vec<T> {
91    fn patterns(&self) -> Vec<String> {
92        self.iter().map(|v| v.as_ref().to_string()).collect()
93    }
94}
95
96macro_rules! array_patterns (($tp:ty, $num:tt) => {
97    impl IntoPattern for [$tp; $num] {
98        fn patterns(&self) -> Vec<String> {
99            self.iter().map(|v| v.to_string()).collect()
100        }
101    }
102});
103
104array_patterns!(&str, 1);
105array_patterns!(&str, 2);
106array_patterns!(&str, 3);
107array_patterns!(&str, 4);
108array_patterns!(&str, 5);
109array_patterns!(&str, 6);
110array_patterns!(&str, 7);
111array_patterns!(&str, 8);
112array_patterns!(&str, 9);
113array_patterns!(&str, 10);
114array_patterns!(&str, 11);
115array_patterns!(&str, 12);
116array_patterns!(&str, 13);
117array_patterns!(&str, 14);
118array_patterns!(&str, 15);
119array_patterns!(&str, 16);
120
121array_patterns!(String, 1);
122array_patterns!(String, 2);
123array_patterns!(String, 3);
124array_patterns!(String, 4);
125array_patterns!(String, 5);
126array_patterns!(String, 6);
127array_patterns!(String, 7);
128array_patterns!(String, 8);
129array_patterns!(String, 9);
130array_patterns!(String, 10);
131array_patterns!(String, 11);
132array_patterns!(String, 12);
133array_patterns!(String, 13);
134array_patterns!(String, 14);
135array_patterns!(String, 15);
136array_patterns!(String, 16);
137
138mod quoter;
139
140#[cfg(feature = "http")]
141mod http_support {
142    use super::ResourcePath;
143    use http::Uri;
144
145    impl ResourcePath for Uri {
146        fn path(&self) -> &str {
147            self.path()
148        }
149
150        fn unquote(s: &str) -> std::borrow::Cow<'_, str> {
151            if let Some(q) = super::quoter::requote(s.as_bytes()) {
152                std::borrow::Cow::Owned(q)
153            } else {
154                std::borrow::Cow::Borrowed(s)
155            }
156        }
157    }
158}