micro_web/request.rs
1//! Request handling module that provides access to HTTP request information and path parameters.
2//!
3//! This module contains the core types for working with HTTP requests in the web framework:
4//! - `RequestContext`: Provides access to request headers and path parameters
5//! - `PathParams`: Handles URL path parameters extracted from request paths
6
7use http::{HeaderMap, Method, Uri, Version};
8use matchit::Params;
9use micro_http::protocol::RequestHeader;
10
11/// Represents the context of an HTTP request, providing access to both the request headers
12/// and any path parameters extracted from the URL.
13///
14/// The lifetime parameters ensure that the request context does not outlive the server
15/// or the request data it references.
16pub struct RequestContext<'server: 'req, 'req> {
17 request_header: &'req RequestHeader,
18 path_params: &'req PathParams<'server, 'req>,
19}
20
21impl<'server, 'req> RequestContext<'server, 'req> {
22 /// Creates a new RequestContext with the given request header and path parameters
23 pub fn new(request_header: &'req RequestHeader, path_params: &'req PathParams<'server, 'req>) -> Self {
24 Self { request_header, path_params }
25 }
26
27 /// Returns a reference to the underlying RequestHeader
28 pub fn request_header(&self) -> &RequestHeader {
29 self.request_header
30 }
31
32 /// Returns the HTTP method of the request
33 pub fn method(&self) -> &Method {
34 self.request_header.method()
35 }
36
37 /// Returns the URI of the request
38 pub fn uri(&self) -> &Uri {
39 self.request_header.uri()
40 }
41
42 /// Returns the HTTP version of the request
43 pub fn version(&self) -> Version {
44 self.request_header.version()
45 }
46
47 /// Returns the HTTP headers of the request
48 pub fn headers(&self) -> &HeaderMap {
49 self.request_header.headers()
50 }
51
52 /// Returns a reference to the path parameters extracted from the request URL
53 pub fn path_params(&self) -> &PathParams {
54 self.path_params
55 }
56}
57
58/// Represents path parameters extracted from the URL path of an HTTP request.
59///
60/// Path parameters are named segments in the URL path that can be extracted and accessed
61/// by name. For example, in the path "/users/{id}", "id" is a path parameter.
62#[derive(Debug, Clone)]
63pub struct PathParams<'server, 'req> {
64 kind: PathParamsKind<'server, 'req>,
65}
66
67/// Internal enum to represent either empty parameters or actual parameters
68#[derive(Debug, Clone)]
69enum PathParamsKind<'server, 'req> {
70 None,
71 Params(Params<'server, 'req>),
72}
73
74impl<'server, 'req> PathParams<'server, 'req> {
75 /// Creates a new PathParams instance from the given Params
76 /// If the params are empty, returns an empty PathParams instance
77 #[inline]
78 fn new(params: Params<'server, 'req>) -> Self {
79 if params.is_empty() { Self::empty() } else { Self { kind: PathParamsKind::Params(params) } }
80 }
81
82 /// Creates an empty PathParams instance with no parameters
83 #[inline]
84 pub fn empty() -> Self {
85 Self { kind: PathParamsKind::None }
86 }
87
88 /// Returns true if there are no path parameters
89 #[inline]
90 pub fn is_empty(&self) -> bool {
91 match &self.kind {
92 PathParamsKind::None => true,
93 PathParamsKind::Params(params) => params.is_empty(),
94 }
95 }
96
97 /// Returns the number of path parameters
98 #[inline]
99 pub fn len(&self) -> usize {
100 match &self.kind {
101 PathParamsKind::None => 0,
102 PathParamsKind::Params(params) => params.len(),
103 }
104 }
105
106 /// Gets the value of a path parameter by its name
107 /// Returns None if the parameter doesn't exist
108 #[inline]
109 pub fn get(&self, key: impl AsRef<str>) -> Option<&'req str> {
110 match &self.kind {
111 PathParamsKind::Params(params) => params.get(key),
112 PathParamsKind::None => None,
113 }
114 }
115}
116
117// Implementation of From trait to convert from Params to PathParams
118impl<'server, 'req> From<Params<'server, 'req>> for PathParams<'server, 'req> {
119 fn from(params: Params<'server, 'req>) -> Self {
120 PathParams::new(params)
121 }
122}