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
13mod 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
67pub 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}