http_serde_ext_ios/
header_map_generic.rs

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