http_serde_ext_ios/
header_map.rs

1use std::{fmt, iter};
2
3use http::{header::GetAll, HeaderValue};
4use serde::{
5    de,
6    ser::{self, SerializeSeq},
7    Deserialize, Deserializer, Serialize, Serializer,
8};
9
10use super::{header_value, insert_header_values, BorrowedNameWrapper, Either, NameWrapper};
11
12type Type = http::HeaderMap;
13const EXPECT_MESSAGE: &str = "a header map";
14
15#[derive(Serialize)]
16struct BorrowedValueWrapper<'a>(#[serde(with = "crate::header_value")] &'a HeaderValue);
17
18struct GetAllWrapper<'a>(GetAll<'a, HeaderValue>);
19
20impl<'a> Serialize for GetAllWrapper<'a> {
21    fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
22        let mut iter = self.0.iter();
23        if let Some(first) = iter.next() {
24            if iter.next().is_none() {
25                if ser.is_human_readable() {
26                    return header_value::serialize(first, ser);
27                } else {
28                    return ser.collect_seq(iter::once(BorrowedValueWrapper(first)));
29                }
30            };
31
32            let count = iter.count() + 2;
33            let mut seq = ser.serialize_seq(Some(count))?;
34            for v in self.0.iter() {
35                seq.serialize_element(&BorrowedValueWrapper(v))?;
36            }
37            seq.end()
38        } else {
39            Err(ser::Error::custom("header has no values"))
40        }
41    }
42}
43
44pub fn serialize<S>(headers: &Type, ser: S) -> Result<S::Ok, S::Error>
45where
46    S: Serializer,
47{
48    ser.collect_map(
49        headers
50            .keys()
51            .map(|k| (BorrowedNameWrapper(k), GetAllWrapper(headers.get_all(k)))),
52    )
53}
54
55#[derive(Deserialize)]
56struct ValueWrapper(#[serde(with = "crate::header_value")] HeaderValue);
57
58struct Visitor {
59    is_human_readable: bool,
60}
61
62impl<'de> de::Visitor<'de> for Visitor {
63    type Value = Type;
64
65    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
66        formatter.write_str(EXPECT_MESSAGE)
67    }
68
69    fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
70    where
71        M: de::MapAccess<'de>,
72    {
73        let mut map = Type::with_capacity(access.size_hint().unwrap_or(0));
74
75        if self.is_human_readable {
76            while let Some((key, val)) = access.next_entry::<NameWrapper, Either<ValueWrapper>>()? {
77                match val {
78                    Either::One(val) => {
79                        map.insert(key.0, val.0);
80                    }
81                    Either::Many(values) => {
82                        insert_header_values::<M, HeaderValue>(
83                            &mut map,
84                            key.0,
85                            values.into_iter().map(|v| v.0),
86                        )?;
87                    }
88                };
89            }
90        } else {
91            while let Some((key, values)) = access.next_entry::<NameWrapper, Vec<ValueWrapper>>()? {
92                insert_header_values::<M, HeaderValue>(
93                    &mut map,
94                    key.0,
95                    values.into_iter().map(|v| v.0),
96                )?;
97            }
98        }
99        Ok(map)
100    }
101}
102
103pub fn deserialize<'de, D>(de: D) -> Result<Type, D::Error>
104where
105    D: Deserializer<'de>,
106{
107    let is_human_readable = de.is_human_readable();
108    de.deserialize_map(Visitor { is_human_readable })
109}
110
111derive_extension_types!(super::Type);