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// ```