http_serde_ext/
response.rs

1use std::mem;
2
3use http::{response::Builder, HeaderMap, StatusCode, Version};
4use serde::{de, Deserialize, Serialize};
5
6type Type<T> = http::Response<T>;
7const STRUCT_NAME: &str = "Response";
8
9#[derive(Serialize)]
10struct BorrowedHead<'a> {
11    #[serde(with = "crate::status_code")]
12    status: StatusCode,
13    #[serde(with = "crate::header_map")]
14    headers: &'a HeaderMap,
15    #[serde(with = "crate::version")]
16    version: Version,
17}
18
19impl<'a, T> From<&'a Type<T>> for BorrowedHead<'a> {
20    fn from(val: &'a Type<T>) -> Self {
21        Self {
22            status: val.status(),
23            headers: val.headers(),
24            version: val.version(),
25        }
26    }
27}
28
29#[derive(Deserialize)]
30struct Head {
31    #[serde(with = "crate::status_code")]
32    status: StatusCode,
33    #[serde(with = "crate::header_map")]
34    headers: HeaderMap,
35    #[serde(with = "crate::version")]
36    version: Version,
37}
38
39impl Head {
40    fn try_into_with_body<T, E>(mut self, body: T) -> Result<Type<T>, E>
41    where
42        E: de::Error,
43    {
44        let mut builder = Builder::new().status(self.status).version(self.version);
45
46        if let Some(headers) = builder.headers_mut() {
47            mem::swap(&mut self.headers, headers);
48        } else {
49            return Err(de::Error::custom("builder doesn't have headers"));
50        }
51
52        builder.body(body).map_err(de::Error::custom)
53    }
54}
55
56serde_request_response!(Type<T>, STRUCT_NAME, Head, BorrowedHead);
57
58derive_extension_types!(super::Type<T>, T);