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.
16#[derive(Debug)]
17pub struct RequestContext<'server: 'req, 'req> {
18    request_header: &'req RequestHeader,
19    path_params: &'req PathParams<'server, 'req>,
20}
21
22impl<'server, 'req> RequestContext<'server, 'req> {
23    /// Creates a new RequestContext with the given request header and path parameters
24    pub fn new(request_header: &'req RequestHeader, path_params: &'req PathParams<'server, 'req>) -> Self {
25        Self { request_header, path_params }
26    }
27
28    /// Returns a reference to the underlying RequestHeader
29    pub fn request_header(&self) -> &RequestHeader {
30        self.request_header
31    }
32
33    /// Returns the HTTP method of the request
34    pub fn method(&self) -> &Method {
35        self.request_header.method()
36    }
37
38    /// Returns the URI of the request
39    pub fn uri(&self) -> &Uri {
40        self.request_header.uri()
41    }
42
43    /// Returns the HTTP version of the request
44    pub fn version(&self) -> Version {
45        self.request_header.version()
46    }
47
48    /// Returns the HTTP headers of the request
49    pub fn headers(&self) -> &HeaderMap {
50        self.request_header.headers()
51    }
52
53    /// Returns a reference to the path parameters extracted from the request URL
54    pub fn path_params(&self) -> &PathParams<'server, 'req> {
55        self.path_params
56    }
57}
58
59/// Represents path parameters extracted from the URL path of an HTTP request.
60///
61/// Path parameters are named segments in the URL path that can be extracted and accessed
62/// by name. For example, in the path "/users/{id}", "id" is a path parameter.
63#[derive(Debug, Clone)]
64pub struct PathParams<'server, 'req> {
65    kind: PathParamsKind<'server, 'req>,
66}
67
68/// Internal enum to represent either empty parameters or actual parameters
69#[derive(Debug, Clone)]
70enum PathParamsKind<'server, 'req> {
71    None,
72    Params(Params<'server, 'req>),
73}
74
75impl<'server, 'req> PathParams<'server, 'req> {
76    /// Creates a new PathParams instance from the given Params
77    /// If the params are empty, returns an empty PathParams instance
78    #[inline]
79    fn new(params: Params<'server, 'req>) -> Self {
80        if params.is_empty() { Self::empty() } else { Self { kind: PathParamsKind::Params(params) } }
81    }
82
83    /// Creates an empty PathParams instance with no parameters
84    #[inline]
85    pub fn empty() -> Self {
86        Self { kind: PathParamsKind::None }
87    }
88
89    /// Returns true if there are no path parameters
90    #[inline]
91    pub fn is_empty(&self) -> bool {
92        match &self.kind {
93            PathParamsKind::None => true,
94            PathParamsKind::Params(params) => params.is_empty(),
95        }
96    }
97
98    /// Returns the number of path parameters
99    #[inline]
100    pub fn len(&self) -> usize {
101        match &self.kind {
102            PathParamsKind::None => 0,
103            PathParamsKind::Params(params) => params.len(),
104        }
105    }
106
107    /// Gets the value of a path parameter by its name
108    /// Returns None if the parameter doesn't exist
109    #[inline]
110    pub fn get(&self, key: impl AsRef<str>) -> Option<&'req str> {
111        match &self.kind {
112            PathParamsKind::Params(params) => params.get(key),
113            PathParamsKind::None => None,
114        }
115    }
116}
117
118// Implementation of From trait to convert from Params to PathParams
119impl<'server, 'req> From<Params<'server, 'req>> for PathParams<'server, 'req> {
120    fn from(params: Params<'server, 'req>) -> Self {
121        PathParams::new(params)
122    }
123}