ntex_router/
lib.rs

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