apigate_core/
parts_ctx.rs1use axum::extract::FromRequestParts;
2
3use crate::error::ApigateError;
4use http::header::{HeaderName, HeaderValue};
5use http::request::Parts;
6
7pub struct PartsCtx<'a> {
8 service: &'static str,
9 route_path: &'static str,
10 parts: &'a mut Parts,
11}
12
13impl<'a> PartsCtx<'a> {
14 pub fn new(service: &'static str, route_path: &'static str, parts: &'a mut Parts) -> Self {
15 Self {
16 service,
17 route_path,
18 parts,
19 }
20 }
21
22 pub fn service(&self) -> &'static str {
23 self.service
24 }
25
26 pub fn route_path(&self) -> &'static str {
27 self.route_path
28 }
29
30 pub fn method(&self) -> &http::Method {
31 &self.parts.method
32 }
33
34 pub fn uri(&self) -> &http::Uri {
35 &self.parts.uri
36 }
37
38 pub fn uri_mut(&mut self) -> &mut http::Uri {
39 &mut self.parts.uri
40 }
41
42 pub fn headers(&self) -> &http::HeaderMap {
43 &self.parts.headers
44 }
45
46 pub fn headers_mut(&mut self) -> &mut http::HeaderMap {
47 &mut self.parts.headers
48 }
49
50 pub fn header(&self, name: &str) -> Option<&str> {
51 self.parts.headers.get(name).and_then(|v| v.to_str().ok())
52 }
53
54 pub fn set_header(
55 &mut self,
56 name: impl TryInto<HeaderName>,
57 value: impl TryInto<HeaderValue>,
58 ) -> Result<(), ApigateError> {
59 let name = name
60 .try_into()
61 .map_err(|_| ApigateError::bad_request("invalid header name"))?;
62 let value = value
63 .try_into()
64 .map_err(|_| ApigateError::bad_request("invalid header value"))?;
65
66 self.parts.headers.insert(name, value);
67 Ok(())
68 }
69
70 pub fn set_header_if_absent(
71 &mut self,
72 name: impl TryInto<HeaderName>,
73 value: impl TryInto<HeaderValue>,
74 ) -> Result<(), ApigateError> {
75 let name = name
76 .try_into()
77 .map_err(|_| ApigateError::bad_request("invalid header name"))?;
78 if self.parts.headers.contains_key(&name) {
79 return Ok(());
80 }
81
82 let value = value
83 .try_into()
84 .map_err(|_| ApigateError::bad_request("invalid header value"))?;
85
86 self.parts.headers.insert(name, value);
87 Ok(())
88 }
89
90 pub fn remove_header(&mut self, name: &str) {
91 self.parts.headers.remove(name);
92 }
93
94 pub fn extensions(&self) -> &http::Extensions {
95 &self.parts.extensions
96 }
97
98 pub fn extensions_mut(&mut self) -> &mut http::Extensions {
99 &mut self.parts.extensions
100 }
101
102 pub async fn extract_path<T>(&mut self) -> Result<T, ApigateError>
103 where
104 T: Send,
105 axum::extract::Path<T>: FromRequestParts<()>,
106 {
107 axum::extract::Path::<T>::from_request_parts(self.parts, &())
108 .await
109 .map(|p| p.0)
110 .map_err(|_| ApigateError::bad_request("invalid path parameters"))
111 }
112}