Skip to main content

actix_router/
resource_path.rs

1use crate::Path;
2
3/// Abstraction over types that can provide a mutable [`Path`] for routing.
4///
5/// This trait is used by the router to extract the request path in a uniform way across different
6/// request types (e.g., Actix Web's `ServiceRequest`). Implementers return a mutable [`Path`]
7/// wrapper so routing can read and potentially normalize/parse the path without requiring the
8/// original request type.
9pub trait Resource {
10    /// Type of resource's path returned in `resource_path`.
11    type Path: ResourcePath;
12
13    /// Returns a mutable reference to the path wrapper used by the router.
14    fn resource_path(&mut self) -> &mut Path<Self::Path>;
15}
16
17pub trait ResourcePath {
18    fn path(&self) -> &str;
19}
20
21impl ResourcePath for String {
22    fn path(&self) -> &str {
23        self.as_str()
24    }
25}
26
27impl ResourcePath for &str {
28    fn path(&self) -> &str {
29        self
30    }
31}
32
33impl ResourcePath for bytestring::ByteString {
34    fn path(&self) -> &str {
35        self
36    }
37}
38
39#[cfg(feature = "http")]
40impl ResourcePath for http::Uri {
41    fn path(&self) -> &str {
42        self.path()
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use bytestring::ByteString;
49
50    use super::*;
51
52    #[test]
53    fn resource_path_implementations_expose_their_path() {
54        let owned = "/owned".to_owned();
55        assert_eq!(<String as ResourcePath>::path(&owned), "/owned");
56
57        let borrowed = "/borrowed";
58        assert_eq!(<&str as ResourcePath>::path(&borrowed), "/borrowed");
59
60        let bytes = ByteString::from("/bytes");
61        assert_eq!(<ByteString as ResourcePath>::path(&bytes), "/bytes");
62    }
63
64    #[cfg(feature = "http")]
65    #[test]
66    fn uri_resource_path_ignores_queries() {
67        let uri = http::Uri::from_static("/resource?query=value");
68
69        assert_eq!(<http::Uri as ResourcePath>::path(&uri), "/resource");
70    }
71}