1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use Parts;
use ;
/// Returns the [`Parts`] of the current request.
///
/// Use this when you need access to multiple components of the request at
/// once. For individual fields, prefer the dedicated accessors
/// ([`method`], [`uri`], [`version`], [`headers`], [`extensions`]).
///
/// # Examples
///
/// ```rust
/// use topcoat::{context::Cx, router::parts};
///
/// async fn log_request(cx: &Cx) {
/// let parts = parts(cx);
/// println!("{} {}", parts.method, parts.uri);
/// }
/// ```
/// Returns the HTTP [`Method`] of the current request.
///
/// [`Method`]: http::Method
///
/// # Examples
///
/// ```rust
/// use topcoat::{context::Cx, router::method};
///
/// async fn is_post(cx: &Cx) -> bool {
/// method(cx) == http::Method::POST
/// }
/// ```
/// Returns the [`Uri`] of the current request.
///
/// [`Uri`]: http::Uri
///
/// # Examples
///
/// ```rust
/// use topcoat::{context::Cx, router::uri};
///
/// async fn current_path(cx: &Cx) -> &str {
/// uri(cx).path()
/// }
/// ```
/// Returns the HTTP [`Version`] of the current request.
///
/// [`Version`]: http::Version
///
/// # Examples
///
/// ```rust
/// use topcoat::{context::Cx, router::version};
///
/// async fn is_http2(cx: &Cx) -> bool {
/// *version(cx) == http::Version::HTTP_2
/// }
/// ```
/// Returns the [`HeaderMap`] of the current request.
///
/// [`HeaderMap`]: http::HeaderMap
///
/// # Examples
///
/// ```rust
/// use topcoat::{context::Cx, router::headers};
///
/// async fn user_agent(cx: &Cx) -> Option<&str> {
/// headers(cx).get("user-agent")?.to_str().ok()
/// }
/// ```
/// Returns the `Content-Type` header of the current request as a string slice,
/// or [`None`] when it is absent or not valid UTF-8.
///
/// # Examples
///
/// ```rust
/// use topcoat::{context::Cx, router::content_type};
///
/// async fn is_json(cx: &Cx) -> bool {
/// content_type(cx).is_some_and(|value| value.starts_with("application/json"))
/// }
/// ```
/// Returns the [`Extensions`] of the current request.
///
/// Extensions carry typed values attached to the request, typically by
/// middleware running before the handler.
///
/// [`Extensions`]: http::Extensions
///
/// # Examples
///
/// ```rust
/// use topcoat::{context::Cx, router::extensions};
///
/// struct RequestId(String);
///
/// async fn request_id(cx: &Cx) -> Option<&str> {
/// extensions(cx).get::<RequestId>().map(|id| id.0.as_str())
/// }
/// ```