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() {
80            Self::empty()
81        } else {
82            Self { kind: PathParamsKind::Params(params) }
83        }
84    }
85
86    /// Creates an empty PathParams instance with no parameters
87    #[inline]
88    pub fn empty() -> Self {
89        Self { kind: PathParamsKind::None }
90    }
91
92    /// Returns true if there are no path parameters
93    #[inline]
94    pub fn is_empty(&self) -> bool {
95        match &self.kind {
96            PathParamsKind::None => true,
97            PathParamsKind::Params(params) => params.is_empty(),
98        }
99    }
100
101    /// Returns the number of path parameters
102    #[inline]
103    pub fn len(&self) -> usize {
104        match &self.kind {
105            PathParamsKind::None => 0,
106            PathParamsKind::Params(params) => params.len(),
107        }
108    }
109
110    /// Gets the value of a path parameter by its name
111    /// Returns None if the parameter doesn't exist
112    #[inline]
113    pub fn get(&self, key: impl AsRef<str>) -> Option<&'req str> {
114        match &self.kind {
115            PathParamsKind::Params(params) => params.get(key),
116            PathParamsKind::None => None,
117        }
118    }
119}
120
121// Implementation of From trait to convert from Params to PathParams
122impl<'server, 'req> From<Params<'server, 'req>> for PathParams<'server, 'req> {
123    fn from(params: Params<'server, 'req>) -> Self {
124        PathParams::new(params)
125    }
126}