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}