1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use std::mem;

use http::{response::Builder, HeaderMap, StatusCode, Version};
use serde::{de, Deserialize, Serialize};

type Type<T> = http::Response<T>;
const STRUCT_NAME: &str = "Response";

#[derive(Serialize)]
struct BorrowedHead<'a> {
    #[serde(with = "crate::status_code")]
    status: StatusCode,
    #[serde(with = "crate::header_map")]
    headers: &'a HeaderMap,
    #[serde(with = "crate::version")]
    version: Version,
}

impl<'a, T> From<&'a Type<T>> for BorrowedHead<'a> {
    fn from(val: &'a Type<T>) -> Self {
        Self {
            status: val.status(),
            headers: val.headers(),
            version: val.version(),
        }
    }
}

#[derive(Deserialize)]
struct Head {
    #[serde(with = "crate::status_code")]
    status: StatusCode,
    #[serde(with = "crate::header_map")]
    headers: HeaderMap,
    #[serde(with = "crate::version")]
    version: Version,
}

impl Head {
    fn try_into_with_body<T, E>(mut self, body: T) -> Result<Type<T>, E>
    where
        E: de::Error,
    {
        let mut builder = Builder::new().status(self.status).version(self.version);

        if let Some(headers) = builder.headers_mut() {
            mem::swap(&mut self.headers, headers);
        } else {
            return Err(de::Error::custom("builder doesn't have headers"));
        }

        builder.body(body).map_err(de::Error::custom)
    }
}

serde_request_response!(Type<T>, STRUCT_NAME, Head, BorrowedHead);

derive_extension_types!(super::Type<T>, T);