poem_openapi/param/
header.rs1use std::ops::{Deref, DerefMut};
2
3use itertools::Either;
4use poem::{Request, RequestBody, Result};
5
6use crate::{
7 ApiExtractor, ApiExtractorType, ExtractParamOptions,
8 error::ParseParamError,
9 registry::{MetaParamIn, MetaSchemaRef, Registry},
10 types::ParseFromParameter,
11};
12
13pub struct Header<T>(pub T);
15
16impl<T> Deref for Header<T> {
17 type Target = T;
18
19 fn deref(&self) -> &Self::Target {
20 &self.0
21 }
22}
23
24impl<T> DerefMut for Header<T> {
25 fn deref_mut(&mut self) -> &mut Self::Target {
26 &mut self.0
27 }
28}
29
30impl<'a, T: ParseFromParameter> ApiExtractor<'a> for Header<T> {
31 const TYPES: &'static [ApiExtractorType] = &[ApiExtractorType::Parameter];
32 const PARAM_IS_REQUIRED: bool = T::IS_REQUIRED;
33
34 type ParamType = T;
35 type ParamRawType = T::RawValueType;
36
37 fn register(registry: &mut Registry) {
38 T::register(registry);
39 }
40
41 fn param_in() -> Option<MetaParamIn> {
42 Some(MetaParamIn::Header)
43 }
44
45 fn param_schema_ref() -> Option<MetaSchemaRef> {
46 Some(T::schema_ref())
47 }
48
49 fn param_raw_type(&self) -> Option<&Self::ParamRawType> {
50 self.0.as_raw_value()
51 }
52
53 async fn from_request(
54 request: &'a Request,
55 _body: &mut RequestBody,
56 param_opts: ExtractParamOptions<Self::ParamType>,
57 ) -> Result<Self> {
58 let mut values = if !param_opts.ignore_case {
59 Either::Left(
60 request
61 .headers()
62 .get_all(param_opts.name)
63 .iter()
64 .filter_map(|value| value.to_str().ok()),
65 )
66 } else {
67 Either::Right(
68 request
69 .headers()
70 .iter()
71 .filter(|(n, _)| n.as_str().eq_ignore_ascii_case(param_opts.name))
72 .filter_map(|(_, value)| value.to_str().ok()),
73 )
74 }
75 .peekable();
76
77 match ¶m_opts.default_value {
78 Some(default_value) if values.peek().is_none() => {
79 return Ok(Self(default_value()));
80 }
81 _ => {}
82 }
83
84 ParseFromParameter::parse_from_parameters(values)
85 .map(Self)
86 .map_err(|err| {
87 ParseParamError {
88 name: param_opts.name,
89 reason: err.into_message(),
90 }
91 .into()
92 })
93 }
94}