1use crate::{HeaderName, HeaderValue, Request, Response};
2use rama_http_headers::HeaderEncode;
3use std::fmt;
4use std::{
5 future::{Future, ready},
6 marker::PhantomData,
7};
8
9pub trait MakeHeaderValueFactory<ReqBody, ResBody>: Send + Sync + 'static {
25 type Maker: MakeHeaderValue<ResBody>;
27
28 fn make_header_value_maker(
30 &self,
31 request: Request<ReqBody>,
32 ) -> impl Future<Output = (Request<ReqBody>, Self::Maker)> + Send + '_;
33}
34
35pub trait MakeHeaderValue<B>: Send + Sync + 'static {
47 fn make_header_value(
49 self,
50 response: Response<B>,
51 ) -> impl Future<Output = (Response<B>, Option<HeaderValue>)> + Send;
52}
53
54impl<B, M> MakeHeaderValue<B> for Option<M>
55where
56 M: MakeHeaderValue<B> + Clone,
57 B: Send + 'static,
58{
59 async fn make_header_value(self, response: Response<B>) -> (Response<B>, Option<HeaderValue>) {
60 match self {
61 Some(m) => m.make_header_value(response).await,
62 None => (response, None),
63 }
64 }
65}
66
67impl<B> MakeHeaderValue<B> for HeaderValue
68where
69 B: Send + 'static,
70{
71 fn make_header_value(
72 self,
73 response: Response<B>,
74 ) -> impl Future<Output = (Response<B>, Option<Self>)> + Send {
75 ready((response, Some(self)))
76 }
77}
78
79impl<B, H> MakeHeaderValue<B> for TypedHeaderAsMaker<H>
80where
81 B: Send + 'static,
82 H: HeaderEncode + Send + Sync + 'static,
83{
84 fn make_header_value(
85 self,
86 response: Response<B>,
87 ) -> impl Future<Output = (Response<B>, Option<HeaderValue>)> + Send {
88 let maybe_value = self.0.encode_to_value();
89 ready((response, maybe_value))
90 }
91}
92
93impl<ReqBody, ResBody> MakeHeaderValueFactory<ReqBody, ResBody> for HeaderValue
94where
95 ReqBody: Send + 'static,
96 ResBody: Send + 'static,
97{
98 type Maker = Self;
99
100 fn make_header_value_maker(
101 &self,
102 req: Request<ReqBody>,
103 ) -> impl Future<Output = (Request<ReqBody>, Self::Maker)> + Send + '_ {
104 ready((req, self.clone()))
105 }
106}
107
108impl<ReqBody, ResBody> MakeHeaderValueFactory<ReqBody, ResBody> for Option<HeaderValue>
109where
110 ReqBody: Send + 'static,
111 ResBody: Send + 'static,
112{
113 type Maker = Self;
114
115 fn make_header_value_maker(
116 &self,
117 req: Request<ReqBody>,
118 ) -> impl Future<Output = (Request<ReqBody>, Self::Maker)> + Send + '_ {
119 ready((req, self.clone()))
120 }
121}
122
123#[derive(Default)]
124pub struct MakeHeaderValueDefault<M>(PhantomData<fn(M)>);
128
129impl<M> MakeHeaderValueDefault<M> {
130 #[inline(always)]
131 pub(super) fn new() -> Self {
132 Self(PhantomData)
133 }
134}
135
136impl<M> fmt::Debug for MakeHeaderValueDefault<M> {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 f.debug_tuple("MakeHeaderValueDefault")
139 .field(&std::any::type_name::<M>())
140 .finish()
141 }
142}
143
144impl<M> Clone for MakeHeaderValueDefault<M> {
145 #[inline(always)]
146 fn clone(&self) -> Self {
147 Self::new()
148 }
149}
150
151impl<M, ReqBody, ResBody> MakeHeaderValueFactory<ReqBody, ResBody> for MakeHeaderValueDefault<M>
152where
153 M: MakeHeaderValue<ResBody> + Default,
154 ReqBody: Send + 'static,
155 ResBody: Send + 'static,
156{
157 type Maker = M;
158
159 fn make_header_value_maker(
160 &self,
161 req: Request<ReqBody>,
162 ) -> impl Future<Output = (Request<ReqBody>, Self::Maker)> + Send + '_ {
163 ready((req, M::default()))
164 }
165}
166
167#[derive(Debug, Clone, Default)]
170pub struct TypedHeaderAsMaker<H>(pub(super) H);
171
172pub trait MakeHeaderValueFactoryFn<ReqBody, ResBody, A>: Send + Sync + 'static {
174 type Maker: MakeHeaderValue<ResBody>;
175
176 fn call(
178 &self,
179 request: Request<ReqBody>,
180 ) -> impl Future<Output = (Request<ReqBody>, Self::Maker)> + Send + '_;
181}
182
183impl<F, Fut, ReqBody, ResBody, M> MakeHeaderValueFactoryFn<ReqBody, ResBody, ()> for F
184where
185 ReqBody: Send + 'static,
186 ResBody: Send + 'static,
187 M: MakeHeaderValue<ResBody>,
188 F: Fn() -> Fut + Send + Sync + 'static,
189 Fut: Future<Output = M> + Send + 'static,
190 M: MakeHeaderValue<ResBody>,
191{
192 type Maker = M;
193
194 async fn call(&self, request: Request<ReqBody>) -> (Request<ReqBody>, M) {
195 let maker = self().await;
196 (request, maker)
197 }
198}
199
200impl<F, Fut, ReqBody, ResBody, M> MakeHeaderValueFactoryFn<ReqBody, ResBody, ((), Request<ReqBody>)>
201 for F
202where
203 ReqBody: Send + 'static,
204 ResBody: Send + 'static,
205 M: MakeHeaderValue<ResBody>,
206 F: Fn(Request<ReqBody>) -> Fut + Send + Sync + 'static,
207 Fut: Future<Output = (Request<ReqBody>, M)> + Send + 'static,
208 M: MakeHeaderValue<ResBody>,
209{
210 type Maker = M;
211
212 async fn call(&self, request: Request<ReqBody>) -> (Request<ReqBody>, M) {
213 let (request, maker) = self(request).await;
214 (request, maker)
215 }
216}
217
218pub struct BoxMakeHeaderValueFactoryFn<F, A> {
220 f: F,
221 _marker: PhantomData<fn(A) -> ()>,
222}
223
224impl<F, A> BoxMakeHeaderValueFactoryFn<F, A> {
225 pub const fn new(f: F) -> Self {
227 Self {
228 f,
229 _marker: PhantomData,
230 }
231 }
232}
233
234impl<F, A> Clone for BoxMakeHeaderValueFactoryFn<F, A>
235where
236 F: Clone,
237{
238 fn clone(&self) -> Self {
239 Self {
240 f: self.f.clone(),
241 _marker: PhantomData,
242 }
243 }
244}
245
246impl<F, A> std::fmt::Debug for BoxMakeHeaderValueFactoryFn<F, A>
247where
248 F: std::fmt::Debug,
249{
250 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
251 f.debug_struct("BoxMakeHeaderValueFn")
252 .field("f", &self.f)
253 .finish()
254 }
255}
256
257impl<ReqBody, ResBody, A, F> MakeHeaderValueFactory<ReqBody, ResBody>
258 for BoxMakeHeaderValueFactoryFn<F, A>
259where
260 A: Send + 'static,
261 F: MakeHeaderValueFactoryFn<ReqBody, ResBody, A>,
262{
263 type Maker = F::Maker;
264
265 fn make_header_value_maker(
266 &self,
267 request: Request<ReqBody>,
268 ) -> impl Future<Output = (Request<ReqBody>, Self::Maker)> + Send + '_ {
269 self.f.call(request)
270 }
271}
272
273pub trait MakeHeaderValueFn<B, A>: Send + Sync + 'static {
277 fn call(
279 self,
280 response: Response<B>,
281 ) -> impl Future<Output = (Response<B>, Option<HeaderValue>)> + Send;
282}
283
284impl<F, Fut, B> MakeHeaderValueFn<B, ()> for F
285where
286 B: Send + 'static,
287 F: FnOnce() -> Fut + Send + Sync + 'static,
288 Fut: Future<Output = Option<HeaderValue>> + Send + 'static,
289{
290 async fn call(self, response: Response<B>) -> (Response<B>, Option<HeaderValue>) {
291 let maybe_value = self().await;
292 (response, maybe_value)
293 }
294}
295
296impl<F, Fut, B> MakeHeaderValueFn<B, Response<B>> for F
297where
298 B: Send + 'static,
299 F: FnOnce(Response<B>) -> Fut + Send + Sync + 'static,
300 Fut: Future<Output = (Response<B>, Option<HeaderValue>)> + Send + 'static,
301{
302 async fn call(self, response: Response<B>) -> (Response<B>, Option<HeaderValue>) {
303 let (response, maybe_value) = self(response).await;
304 (response, maybe_value)
305 }
306}
307
308pub struct BoxMakeHeaderValueFn<F, A> {
310 f: F,
311 _marker: PhantomData<fn(A) -> ()>,
312}
313
314impl<F, A> BoxMakeHeaderValueFn<F, A> {
315 pub const fn new(f: F) -> Self {
317 Self {
318 f,
319 _marker: PhantomData,
320 }
321 }
322}
323
324impl<F, A> Clone for BoxMakeHeaderValueFn<F, A>
325where
326 F: Clone,
327{
328 fn clone(&self) -> Self {
329 Self {
330 f: self.f.clone(),
331 _marker: PhantomData,
332 }
333 }
334}
335
336impl<F, A> std::fmt::Debug for BoxMakeHeaderValueFn<F, A>
337where
338 F: std::fmt::Debug,
339{
340 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
341 f.debug_struct("BoxMakeHeaderValueFn")
342 .field("f", &self.f)
343 .finish()
344 }
345}
346
347impl<B, A, F> MakeHeaderValue<B> for BoxMakeHeaderValueFn<F, A>
348where
349 A: Send + 'static,
350 F: MakeHeaderValueFn<B, A>,
351{
352 fn make_header_value(
353 self,
354 response: Response<B>,
355 ) -> impl Future<Output = (Response<B>, Option<HeaderValue>)> + Send {
356 self.f.call(response)
357 }
358}
359
360impl<F, Fut, ReqBody, ResBody> MakeHeaderValueFactoryFn<ReqBody, ResBody, ((), (), ())> for F
361where
362 ReqBody: Send + 'static,
363 ResBody: Send + 'static,
364 F: Fn() -> Fut + Clone + Send + Sync + 'static,
365 Fut: Future<Output = Option<HeaderValue>> + Send + 'static,
366{
367 type Maker = BoxMakeHeaderValueFn<F, ()>;
368
369 async fn call(&self, request: Request<ReqBody>) -> (Request<ReqBody>, Self::Maker) {
370 let maker = self.clone();
371 (request, BoxMakeHeaderValueFn::new(maker))
372 }
373}
374
375impl<F, Fut, ReqBody, ResBody>
376 MakeHeaderValueFactoryFn<ReqBody, ResBody, ((), (), Response<ResBody>)> for F
377where
378 ReqBody: Send + 'static,
379 ResBody: Send + 'static,
380 F: Fn(Response<ResBody>) -> Fut + Clone + Send + Sync + 'static,
381 Fut: Future<Output = (Response<ResBody>, Option<HeaderValue>)> + Send + 'static,
382{
383 type Maker = BoxMakeHeaderValueFn<F, Response<ResBody>>;
384
385 async fn call(&self, request: Request<ReqBody>) -> (Request<ReqBody>, Self::Maker) {
386 let maker = self.clone();
387 (request, BoxMakeHeaderValueFn::new(maker))
388 }
389}
390
391#[derive(Debug, Clone, Copy)]
392pub(super) enum InsertHeaderMode {
393 Override,
394 Append,
395 IfNotPresent,
396}
397
398impl InsertHeaderMode {
399 pub(super) async fn apply<B, M>(
400 self,
401 header_name: &HeaderName,
402 response: Response<B>,
403 make: M,
404 ) -> Response<B>
405 where
406 B: Send + 'static,
407 M: MakeHeaderValue<B>,
408 {
409 match self {
410 Self::Override => {
411 let (mut response, maybe_value) = make.make_header_value(response).await;
412 if let Some(value) = maybe_value {
413 response.headers_mut().insert(header_name.clone(), value);
414 }
415 response
416 }
417 Self::IfNotPresent => {
418 if !response.headers().contains_key(header_name) {
419 let (mut response, maybe_value) = make.make_header_value(response).await;
420 if let Some(value) = maybe_value {
421 response.headers_mut().insert(header_name.clone(), value);
422 }
423 response
424 } else {
425 response
426 }
427 }
428 Self::Append => {
429 let (mut response, maybe_value) = make.make_header_value(response).await;
430 if let Some(value) = maybe_value {
431 response.headers_mut().append(header_name.clone(), value);
432 }
433 response
434 }
435 }
436 }
437}