1use std::convert::TryFrom;
23use std::sync::Arc;
24
25use http::header::{HeaderMap, HeaderName, HeaderValue};
26
27use self::sealed::{WithDefaultHeader_, WithHeader_, WithHeaders_};
28use crate::filter::{Filter, Map, WrapSealed};
29use crate::reply::Reply;
30
31pub fn header<K, V>(name: K, value: V) -> WithHeader
50where
51 HeaderName: TryFrom<K>,
52 <HeaderName as TryFrom<K>>::Error: Into<http::Error>,
53 HeaderValue: TryFrom<V>,
54 <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
55{
56 let (name, value) = assert_name_and_value(name, value);
57 WithHeader { name, value }
58}
59
60pub fn headers(headers: HeaderMap) -> WithHeaders {
84 WithHeaders {
85 headers: Arc::new(headers),
86 }
87}
88
89pub fn default_header<K, V>(name: K, value: V) -> WithDefaultHeader
111where
112 HeaderName: TryFrom<K>,
113 <HeaderName as TryFrom<K>>::Error: Into<http::Error>,
114 HeaderValue: TryFrom<V>,
115 <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
116{
117 let (name, value) = assert_name_and_value(name, value);
118 WithDefaultHeader { name, value }
119}
120
121#[derive(Clone, Debug)]
123pub struct WithHeader {
124 name: HeaderName,
125 value: HeaderValue,
126}
127
128impl<F, R> WrapSealed<F> for WithHeader
129where
130 F: Filter<Extract = (R,)>,
131 R: Reply,
132{
133 type Wrapped = Map<F, WithHeader_>;
134
135 fn wrap(&self, filter: F) -> Self::Wrapped {
136 let with = WithHeader_ { with: self.clone() };
137 filter.map(with)
138 }
139}
140
141#[derive(Clone, Debug)]
143pub struct WithHeaders {
144 headers: Arc<HeaderMap>,
145}
146
147impl<F, R> WrapSealed<F> for WithHeaders
148where
149 F: Filter<Extract = (R,)>,
150 R: Reply,
151{
152 type Wrapped = Map<F, WithHeaders_>;
153
154 fn wrap(&self, filter: F) -> Self::Wrapped {
155 let with = WithHeaders_ { with: self.clone() };
156 filter.map(with)
157 }
158}
159
160#[derive(Clone, Debug)]
162pub struct WithDefaultHeader {
163 name: HeaderName,
164 value: HeaderValue,
165}
166
167impl<F, R> WrapSealed<F> for WithDefaultHeader
168where
169 F: Filter<Extract = (R,)>,
170 R: Reply,
171{
172 type Wrapped = Map<F, WithDefaultHeader_>;
173
174 fn wrap(&self, filter: F) -> Self::Wrapped {
175 let with = WithDefaultHeader_ { with: self.clone() };
176 filter.map(with)
177 }
178}
179
180fn assert_name_and_value<K, V>(name: K, value: V) -> (HeaderName, HeaderValue)
181where
182 HeaderName: TryFrom<K>,
183 <HeaderName as TryFrom<K>>::Error: Into<http::Error>,
184 HeaderValue: TryFrom<V>,
185 <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
186{
187 let name = <HeaderName as TryFrom<K>>::try_from(name)
188 .map_err(Into::into)
189 .unwrap_or_else(|_| panic!("invalid header name"));
190
191 let value = <HeaderValue as TryFrom<V>>::try_from(value)
192 .map_err(Into::into)
193 .unwrap_or_else(|_| panic!("invalid header value"));
194
195 (name, value)
196}
197
198mod sealed {
199 use super::{WithDefaultHeader, WithHeader, WithHeaders};
200 use crate::generic::{Func, One};
201 use crate::reply::{Reply, Reply_};
202
203 #[derive(Clone)]
204 #[allow(missing_debug_implementations)]
205 pub struct WithHeader_ {
206 pub(super) with: WithHeader,
207 }
208
209 impl<R: Reply> Func<One<R>> for WithHeader_ {
210 type Output = Reply_;
211
212 fn call(&self, args: One<R>) -> Self::Output {
213 let mut resp = args.0.into_response();
214 resp.headers_mut()
216 .insert(&self.with.name, self.with.value.clone());
217 Reply_(resp)
218 }
219 }
220
221 #[derive(Clone)]
222 #[allow(missing_debug_implementations)]
223 pub struct WithHeaders_ {
224 pub(super) with: WithHeaders,
225 }
226
227 impl<R: Reply> Func<One<R>> for WithHeaders_ {
228 type Output = Reply_;
229
230 fn call(&self, args: One<R>) -> Self::Output {
231 let mut resp = args.0.into_response();
232 for (name, value) in &*self.with.headers {
233 resp.headers_mut().insert(name, value.clone());
234 }
235 Reply_(resp)
236 }
237 }
238
239 #[derive(Clone)]
240 #[allow(missing_debug_implementations)]
241 pub struct WithDefaultHeader_ {
242 pub(super) with: WithDefaultHeader,
243 }
244
245 impl<R: Reply> Func<One<R>> for WithDefaultHeader_ {
246 type Output = Reply_;
247
248 fn call(&self, args: One<R>) -> Self::Output {
249 let mut resp = args.0.into_response();
250 resp.headers_mut()
251 .entry(&self.with.name)
252 .or_insert_with(|| self.with.value.clone());
253
254 Reply_(resp)
255 }
256 }
257}