rama_http/layer/set_header/request/
header.rs1use crate::{HeaderName, HeaderValue, Request};
2use rama_http_headers::HeaderEncode;
3use std::fmt;
4use std::{
5 future::{Future, ready},
6 marker::PhantomData,
7};
8
9pub trait MakeHeaderValue<B>: Send + Sync + 'static {
21 fn make_header_value(
23 &self,
24 req: Request<B>,
25 ) -> impl Future<Output = (Request<B>, Option<HeaderValue>)> + Send + '_;
26}
27
28#[derive(Default)]
29pub struct MakeHeaderValueDefault<M>(PhantomData<fn(M)>);
33
34impl<M> MakeHeaderValueDefault<M> {
35 #[inline(always)]
36 pub(super) fn new() -> Self {
37 Self(PhantomData)
38 }
39}
40
41impl<M> fmt::Debug for MakeHeaderValueDefault<M> {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 f.debug_tuple("MakeHeaderValueDefault")
44 .field(&std::any::type_name::<M>())
45 .finish()
46 }
47}
48
49impl<M> Clone for MakeHeaderValueDefault<M> {
50 #[inline(always)]
51 fn clone(&self) -> Self {
52 Self::new()
53 }
54}
55
56impl<M, ReqBody> MakeHeaderValue<ReqBody> for MakeHeaderValueDefault<M>
57where
58 M: MakeHeaderValue<ReqBody> + Default,
59 ReqBody: Send + 'static,
60{
61 #[inline(always)]
62 async fn make_header_value(
63 &self,
64 req: Request<ReqBody>,
65 ) -> (Request<ReqBody>, Option<HeaderValue>) {
66 M::default().make_header_value(req).await
67 }
68}
69
70#[derive(Debug, Clone, Default)]
73pub struct TypedHeaderAsMaker<H>(pub(super) H);
74
75pub trait MakeHeaderValueFn<B, A>: Send + Sync + 'static {
77 fn call(
79 &self,
80 req: Request<B>,
81 ) -> impl Future<Output = (Request<B>, Option<HeaderValue>)> + Send + '_;
82}
83
84impl<F, Fut, B> MakeHeaderValueFn<B, ()> for F
85where
86 B: Send + 'static,
87 F: Fn() -> Fut + Send + Sync + 'static,
88 Fut: Future<Output = Option<HeaderValue>> + Send + 'static,
89{
90 async fn call(&self, req: Request<B>) -> (Request<B>, Option<HeaderValue>) {
91 let maybe_value = self().await;
92 (req, maybe_value)
93 }
94}
95
96impl<F, Fut, B> MakeHeaderValueFn<B, ((), B)> for F
97where
98 B: Send + 'static,
99 F: Fn(Request<B>) -> Fut + Send + Sync + 'static,
100 Fut: Future<Output = (Request<B>, Option<HeaderValue>)> + Send + 'static,
101{
102 async fn call(&self, req: Request<B>) -> (Request<B>, Option<HeaderValue>) {
103 let (req, maybe_value) = self(req).await;
104 (req, maybe_value)
105 }
106}
107
108pub struct BoxMakeHeaderValueFn<F, A> {
110 f: F,
111 _marker: PhantomData<fn(A) -> ()>,
112}
113
114impl<F, A> BoxMakeHeaderValueFn<F, A> {
115 pub const fn new(f: F) -> Self {
117 Self {
118 f,
119 _marker: PhantomData,
120 }
121 }
122}
123
124impl<F, A> Clone for BoxMakeHeaderValueFn<F, A>
125where
126 F: Clone,
127{
128 fn clone(&self) -> Self {
129 Self {
130 f: self.f.clone(),
131 _marker: PhantomData,
132 }
133 }
134}
135
136impl<F, A> std::fmt::Debug for BoxMakeHeaderValueFn<F, A>
137where
138 F: std::fmt::Debug,
139{
140 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
141 f.debug_struct("BoxMakeHeaderValueFn")
142 .field("f", &self.f)
143 .finish()
144 }
145}
146
147impl<B, A, F> MakeHeaderValue<B> for BoxMakeHeaderValueFn<F, A>
148where
149 A: Send + 'static,
150 F: MakeHeaderValueFn<B, A>,
151{
152 fn make_header_value(
153 &self,
154 req: Request<B>,
155 ) -> impl Future<Output = (Request<B>, Option<HeaderValue>)> + Send + '_ {
156 self.f.call(req)
157 }
158}
159
160impl<B, M> MakeHeaderValue<B> for Option<M>
161where
162 M: MakeHeaderValue<B> + Clone,
163 B: Send + 'static,
164{
165 async fn make_header_value(&self, req: Request<B>) -> (Request<B>, Option<HeaderValue>) {
166 match self {
167 Some(m) => m.make_header_value(req).await,
168 None => (req, None),
169 }
170 }
171}
172
173impl<B> MakeHeaderValue<B> for HeaderValue
174where
175 B: Send + 'static,
176{
177 fn make_header_value(
178 &self,
179 req: Request<B>,
180 ) -> impl Future<Output = (Request<B>, Option<Self>)> + Send + '_ {
181 ready((req, Some(self.clone())))
182 }
183}
184
185impl<B, H> MakeHeaderValue<B> for TypedHeaderAsMaker<H>
186where
187 B: Send + 'static,
188 H: HeaderEncode + Send + Sync + 'static,
189{
190 fn make_header_value(
191 &self,
192 req: Request<B>,
193 ) -> impl Future<Output = (Request<B>, Option<HeaderValue>)> + Send {
194 let maybe_value = self.0.encode_to_value();
195 ready((req, maybe_value))
196 }
197}
198
199#[derive(Debug, Clone, Copy)]
200pub(super) enum InsertHeaderMode {
201 Override,
202 Append,
203 IfNotPresent,
204}
205
206impl InsertHeaderMode {
207 pub(super) async fn apply<B, M>(
208 self,
209 header_name: &HeaderName,
210 req: Request<B>,
211 make: &M,
212 ) -> Request<B>
213 where
214 B: Send + 'static,
215 M: MakeHeaderValue<B>,
216 {
217 match self {
218 Self::Override => {
219 let (mut req, maybe_value) = make.make_header_value(req).await;
220 if let Some(value) = maybe_value {
221 req.headers_mut().insert(header_name.clone(), value);
222 }
223 req
224 }
225 Self::IfNotPresent => {
226 if !req.headers().contains_key(header_name) {
227 let (mut req, maybe_value) = make.make_header_value(req).await;
228 if let Some(value) = maybe_value {
229 req.headers_mut().insert(header_name.clone(), value);
230 }
231 req
232 } else {
233 req
234 }
235 }
236 Self::Append => {
237 let (mut req, maybe_value) = make.make_header_value(req).await;
238 if let Some(value) = maybe_value {
239 req.headers_mut().append(header_name.clone(), value);
240 }
241 req
242 }
243 }
244 }
245}