Skip to main content

trillium_router/
router_conn_ext.rs

1use crate::{CapturesNewType, RouteSpecNewType};
2use trillium::Conn;
3
4/**
5Extends trillium::Conn with accessors for router params.
6*/
7pub trait RouterConnExt {
8    /**
9    Retrieves a captured param from the conn. Note that this will only
10    be Some if the exact param is present in the matched route.
11
12    Routefinder params are defined starting with a colon, but the
13    colon is not needed when fetching the param.
14
15    ```
16    use trillium::{conn_unwrap, Conn};
17    use trillium_router::{Router, RouterConnExt};
18
19    let router = Router::new().get("/pages/:page_name", |conn: Conn| async move {
20        let page_name = conn_unwrap!(conn.param("page_name"), conn);
21        let content = format!("you have reached the page named {}", page_name);
22        conn.ok(content)
23    });
24
25    use trillium_testing::prelude::*;
26    assert_ok!(
27        get("/pages/trillium").on(&router),
28        "you have reached the page named trillium"
29    );
30    ```
31    */
32
33    fn param<'a>(&'a self, param: &str) -> Option<&'a str>;
34
35    /// Retrieves the wildcard match from the conn. Note that this will
36    /// only be Some if the matched route contains a wildcard, as
37    /// expressed by a "*" in the routefinder route spec.
38    ///
39    /// ```
40    /// use trillium::{conn_unwrap, Conn};
41    /// use trillium_router::{Router, RouterConnExt};
42    ///
43    /// let router = Router::new().get("/pages/*", |conn: Conn| async move {
44    ///     let wildcard = conn_unwrap!(conn.wildcard(), conn);
45    ///     let content = format!("the wildcard matched {}", wildcard);
46    ///     conn.ok(content)
47    /// });
48    ///
49    /// use trillium_testing::prelude::*;
50    /// assert_ok!(
51    ///     get("/pages/this/is/a/wildcard/match").on(&router),
52    ///     "the wildcard matched this/is/a/wildcard/match"
53    /// );
54    /// ```
55
56    fn wildcard(&self) -> Option<&str>;
57
58    /// Retrieves the matched route specification
59    /// ```
60    /// use trillium::{conn_unwrap, Conn};
61    /// use trillium_router::{Router, RouterConnExt};
62    ///
63    /// let router = Router::new().get("/pages/:page_id", |conn: Conn| async move {
64    ///     let route = conn_unwrap!(conn.route(), conn).to_string();
65    ///     conn.ok(format!("route was {route}"))
66    /// });
67    ///
68    /// use trillium_testing::prelude::*;
69    /// assert_ok!(
70    ///     get("/pages/12345").on(&router),
71    ///     "route was /pages/:page_id"
72    /// );
73    /// ```
74    fn route(&self) -> Option<&str>;
75}
76
77impl RouterConnExt for Conn {
78    fn param<'a>(&'a self, param: &str) -> Option<&'a str> {
79        self.state().and_then(|CapturesNewType(p)| p.get(param))
80    }
81
82    fn wildcard(&self) -> Option<&str> {
83        self.state().and_then(|CapturesNewType(p)| p.wildcard())
84    }
85
86    fn route(&self) -> Option<&str> {
87        self.state().and_then(|RouteSpecNewType(r)| r.source())
88    }
89}
90
91// ```
92// use trillium::{conn_unwrap, Conn};
93// use trillium_router::{Router, RouterConnExt};
94
95// let router = Router::new().get("/pages/*", |conn: Conn| async move {
96//     let wildcard = conn_unwrap!(conn.wildcard(), conn);
97//     let content = format!("the wildcard matched {}", wildcard);
98//     conn.ok(content)
99// });
100
101// use trillium_testing::prelude::*;
102// assert_ok!(
103//     get("/pages/this/is/a/wildcard/match").on(&router),
104//     "the wildcard matched this/is/a/wildcard/match"
105// );
106// ```