http_serde/
lib.rs

1#![doc = include_str!("../README.md")]
2
3/// The HTTP crate
4pub use http;
5
6/// For `http::HeaderMap`
7///
8/// `#[serde(with = "http_serde::header_map")]`
9pub mod header_map {
10    use http::header::{GetAll, HeaderName};
11    use http::{HeaderMap, HeaderValue};
12    use serde::de;
13    use serde::de::{Deserializer, MapAccess, Unexpected, Visitor};
14    use serde::ser::SerializeSeq;
15    use serde::{Serialize, Serializer};
16    use std::borrow::Cow;
17    use std::fmt;
18
19    struct ToSeq<'a>(GetAll<'a, HeaderValue>);
20
21    impl<'a> Serialize for ToSeq<'a> {
22        fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
23            let count = self.0.iter().count();
24            if ser.is_human_readable() {
25                if count == 1 {
26                    if let Some(v) = self.0.iter().next() {
27                        if let Ok(s) = v.to_str() {
28                            return ser.serialize_str(s);
29                        }
30                    }
31                }
32                ser.collect_seq(self.0.iter().filter_map(|v| v.to_str().ok()))
33            } else {
34                let mut seq = ser.serialize_seq(Some(count))?;
35                for v in &self.0 {
36                    seq.serialize_element(v.as_bytes())?;
37                }
38                seq.end()
39            }
40        }
41    }
42
43    /// Implementation detail. Use derive annotations instead.
44    pub fn serialize<S: Serializer>(headers: &HeaderMap, ser: S) -> Result<S::Ok, S::Error> {
45        ser.collect_map(
46            headers
47                .keys()
48                .map(|k| (k.as_str(), ToSeq(headers.get_all(k)))),
49        )
50    }
51
52    enum OneOrMore<'a> {
53        One(Cow<'a, [u8]>),
54        More(Vec<Cow<'a, [u8]>>),
55    }
56
57    #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
58    impl<'de> serde::Deserialize<'de> for OneOrMore<'de> {
59        fn deserialize<D: Deserializer<'de>>(des: D) -> Result<Self, D::Error> {
60            des.deserialize_any(OneOrMoreVisitor)
61        }
62    }
63
64    struct OneOrMoreVisitor;
65
66    impl<'de> Visitor<'de> for OneOrMoreVisitor {
67        type Value = OneOrMore<'de>;
68        #[inline]
69        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
70            formatter.write_str("byte strings")
71        }
72
73        fn visit_seq<A: de::SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
74            let mut out = Vec::with_capacity(access.size_hint().unwrap_or(0));
75            while let Some(OneOrMore::One(el)) = access.next_element::<OneOrMore<'de>>()? {
76                out.push(el);
77            }
78            Ok(OneOrMore::More(out))
79        }
80
81        fn visit_borrowed_str<E: de::Error>(self, s: &'de str) -> Result<Self::Value, E> {
82            Ok(OneOrMore::One(Cow::Borrowed(s.as_bytes())))
83        }
84
85        fn visit_str<E: de::Error>(self, s: &str) -> Result<Self::Value, E> {
86            Ok(OneOrMore::One(Cow::Owned(s.into())))
87        }
88
89        fn visit_string<E: de::Error>(self, s: String) -> Result<Self::Value, E> {
90            Ok(OneOrMore::One(Cow::Owned(s.into_bytes())))
91        }
92
93        fn visit_borrowed_bytes<E: de::Error>(self, s: &'de [u8]) -> Result<Self::Value, E> {
94            Ok(OneOrMore::One(Cow::Borrowed(s)))
95        }
96
97        fn visit_bytes<E: de::Error>(self, s: &[u8]) -> Result<Self::Value, E> {
98            Ok(OneOrMore::One(Cow::Owned(s.into())))
99        }
100
101        fn visit_byte_buf<E: de::Error>(self, s: Vec<u8>) -> Result<Self::Value, E> {
102            Ok(OneOrMore::One(Cow::Owned(s)))
103        }
104    }
105
106    pub(crate) struct HeaderMapVisitor {
107        is_human_readable: bool,
108    }
109
110    impl HeaderMapVisitor {
111        #[inline]
112        pub(crate) fn new<'de, D: Deserializer<'de>>(d: &D) -> Self {
113            Self {
114                is_human_readable: d.is_human_readable(),
115            }
116        }
117
118        #[inline(never)]
119        fn single<E: de::Error>(&self, map: &mut HeaderMap, key: &str, val: Vec<u8>) -> Result<(), E> {
120            let key = HeaderName::from_bytes(key.as_bytes())
121                    .map_err(|_| de::Error::invalid_value(Unexpected::Str(key), self))?;
122            let val = HeaderValue::try_from(val).map_err(de::Error::custom)?;
123            map.try_insert(key, val).map_err(de::Error::custom)?;
124            Ok(())
125        }
126
127        fn multi<E: de::Error>(&self, map: &mut HeaderMap, key: &str, mut vals: Vec<Cow<'_, [u8]>>) -> Result<(), E> {
128            if vals.len() == 1 {
129                return self.single(map, key, vals.remove(0).into_owned());
130            }
131            let key = HeaderName::from_bytes(key.as_bytes())
132                    .map_err(|_| de::Error::invalid_value(Unexpected::Str(key), self))?;
133            for val in vals {
134                let val = HeaderValue::try_from(val.into_owned()).map_err(de::Error::custom)?;
135                map.try_append(&key, val).map_err(de::Error::custom)?;
136            }
137            Ok(())
138        }
139    }
140
141    impl<'de> Visitor<'de> for HeaderMapVisitor {
142        type Value = HeaderMap;
143
144        // Format a message stating what data this Visitor expects to receive.
145        #[inline]
146        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
147            formatter.write_str("multi-valued HeaderMap")
148        }
149
150        #[inline]
151        fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
152            deserializer.deserialize_map(self)
153        }
154
155        fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
156        where
157            M: MapAccess<'de>,
158        {
159            let mut map = HeaderMap::try_with_capacity(access.size_hint().unwrap_or(0))
160                .map_err(de::Error::custom)?;
161
162            if !self.is_human_readable {
163                while let Some((key, arr)) = access.next_entry::<Cow<str>, Vec<Cow<[u8]>>>()? {
164                    self.multi(&mut map, &key, arr)?;
165                }
166            } else {
167                while let Some((key, val)) = access.next_entry::<Cow<str>, OneOrMore>()? {
168                    match val {
169                        OneOrMore::One(val) => self.single(&mut map, &key, val.into_owned().into())?,
170                        OneOrMore::More(arr) => self.multi(&mut map, &key, arr)?,
171                    };
172                }
173            }
174            Ok(map)
175        }
176    }
177
178    /// Implementation detail.
179    pub fn deserialize<'de, D>(de: D) -> Result<HeaderMap, D::Error>
180    where
181        D: Deserializer<'de>,
182    {
183        let is_human_readable = de.is_human_readable();
184        de.deserialize_map(HeaderMapVisitor { is_human_readable })
185    }
186}
187
188/// For `http::StatusCode`
189///
190/// `#[serde(with = "http_serde::status_code")]`
191pub mod status_code {
192    use http::StatusCode;
193    use serde::de;
194    use serde::de::{Unexpected, Visitor};
195    use serde::{Deserializer, Serializer};
196    use std::fmt;
197
198    /// Implementation detail. Use derive annotations instead.
199    #[inline]
200    pub fn serialize<S: Serializer>(status: &StatusCode, ser: S) -> Result<S::Ok, S::Error> {
201        ser.serialize_u16(status.as_u16())
202    }
203
204    pub(crate) struct StatusVisitor;
205
206    impl StatusVisitor {
207        #[inline]
208        pub(crate) fn new<'de, D: Deserializer<'de>>(_: &D) -> Self {
209            Self
210        }
211    }
212
213    impl StatusVisitor {
214        #[inline(never)]
215        fn make<E: de::Error>(&self, val: u64) -> Result<StatusCode, E> {
216            if (100..1000).contains(&val) {
217                if let Ok(s) = StatusCode::from_u16(val as u16) {
218                    return Ok(s);
219                }
220            }
221            Err(de::Error::invalid_value(Unexpected::Unsigned(val), self))
222        }
223    }
224
225    impl<'de> Visitor<'de> for StatusVisitor {
226        type Value = StatusCode;
227
228        #[inline]
229        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
230            formatter.write_str("status code")
231        }
232
233        #[inline]
234        fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
235            deserializer.deserialize_u16(self)
236        }
237
238        #[inline]
239        fn visit_i64<E: de::Error>(self, val: i64) -> Result<Self::Value, E> {
240            self.make(val as _)
241        }
242
243        #[inline]
244        fn visit_u64<E: de::Error>(self, val: u64) -> Result<Self::Value, E> {
245            self.make(val)
246        }
247    }
248
249    /// Implementation detail.
250    #[inline]
251    pub fn deserialize<'de, D>(de: D) -> Result<StatusCode, D::Error>
252    where
253        D: Deserializer<'de>,
254    {
255        de.deserialize_u16(StatusVisitor)
256    }
257}
258
259/// For `http::Method`
260///
261/// `#[serde(with = "http_serde::method")]`
262pub mod method {
263    use http::Method;
264    use serde::de;
265    use serde::de::{Unexpected, Visitor};
266    use serde::{Deserializer, Serializer};
267    use std::fmt;
268
269    /// Implementation detail. Use derive annotations instead.
270    #[inline]
271    pub fn serialize<S: Serializer>(method: &Method, ser: S) -> Result<S::Ok, S::Error> {
272        ser.serialize_str(method.as_str())
273    }
274
275    pub(crate) struct MethodVisitor;
276
277    impl MethodVisitor {
278        #[inline]
279        pub(crate) fn new<'de, D: Deserializer<'de>>(_: &D) -> Self {
280            Self
281        }
282    }
283
284    impl<'de> Visitor<'de> for MethodVisitor {
285        type Value = Method;
286
287        #[inline]
288        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
289            formatter.write_str("method name")
290        }
291
292        #[inline]
293        fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
294            deserializer.deserialize_str(self)
295        }
296
297        fn visit_str<E: de::Error>(self, val: &str) -> Result<Self::Value, E> {
298            val.parse()
299                .map_err(|_| de::Error::invalid_value(Unexpected::Str(val), &self))
300        }
301    }
302
303    /// Implementation detail.
304    #[inline]
305    pub fn deserialize<'de, D>(de: D) -> Result<Method, D::Error>
306    where
307        D: Deserializer<'de>,
308    {
309        de.deserialize_str(MethodVisitor)
310    }
311}
312
313/// For `http::Uri`
314///
315/// `#[serde(with = "http_serde::uri")]`
316pub mod uri {
317    use http::Uri;
318    use serde::de;
319    use serde::de::{Unexpected, Visitor};
320    use serde::{Deserializer, Serializer};
321    use std::convert::TryInto;
322    use std::fmt;
323
324    /// Implementation detail. Use derive annotations instead.
325    #[inline]
326    pub fn serialize<S: Serializer>(uri: &Uri, ser: S) -> Result<S::Ok, S::Error> {
327        ser.collect_str(&uri)
328    }
329
330    pub(crate) struct UriVisitor;
331
332    impl UriVisitor {
333        #[inline]
334        pub(crate) fn new<'de, D: Deserializer<'de>>(_: &D) -> Self {
335            Self
336        }
337    }
338
339    impl<'de> Visitor<'de> for UriVisitor {
340        type Value = Uri;
341
342        #[inline]
343        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
344            formatter.write_str("uri")
345        }
346
347        #[inline]
348        fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
349            deserializer.deserialize_str(self)
350        }
351
352        fn visit_str<E: de::Error>(self, val: &str) -> Result<Self::Value, E> {
353            val.parse()
354                .map_err(|_| de::Error::invalid_value(Unexpected::Str(val), &self))
355        }
356
357        fn visit_string<E: de::Error>(self, val: String) -> Result<Self::Value, E> {
358            val.try_into().map_err(de::Error::custom)
359        }
360    }
361
362    /// Implementation detail.
363    #[inline]
364    pub fn deserialize<'de, D>(de: D) -> Result<Uri, D::Error>
365    where
366        D: Deserializer<'de>,
367    {
368        de.deserialize_str(UriVisitor)
369    }
370}
371
372/// For `http::uri::Authority`
373///
374/// `#[serde(with = "http_serde::authority")]`
375pub mod authority {
376    use http::uri::Authority;
377    use serde::de;
378    use serde::de::{Unexpected, Visitor};
379    use serde::{Deserializer, Serializer};
380    use std::convert::TryInto;
381    use std::fmt;
382
383    /// Implementation detail. Use derive annotations instead.
384    #[inline]
385    pub fn serialize<S: Serializer>(authority: &Authority, ser: S) -> Result<S::Ok, S::Error> {
386        ser.collect_str(&authority)
387    }
388
389    pub(crate) struct AuthorityVisitor;
390
391    impl AuthorityVisitor {
392        #[inline]
393        pub(crate) fn new<'de, D: Deserializer<'de>>(_: &D) -> Self {
394            Self
395        }
396    }
397
398    impl<'de> Visitor<'de> for AuthorityVisitor {
399        type Value = Authority;
400
401        #[inline]
402        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
403            formatter.write_str("authority")
404        }
405
406        #[inline]
407        fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
408            deserializer.deserialize_str(self)
409        }
410
411        fn visit_str<E: de::Error>(self, val: &str) -> Result<Self::Value, E> {
412            val.parse()
413                .map_err(|_| de::Error::invalid_value(Unexpected::Str(val), &self))
414        }
415
416        fn visit_string<E: de::Error>(self, val: String) -> Result<Self::Value, E> {
417            val.try_into().map_err(de::Error::custom)
418        }
419    }
420
421    /// Implementation detail.
422    #[inline]
423    pub fn deserialize<'de, D>(de: D) -> Result<Authority, D::Error>
424    where
425        D: Deserializer<'de>,
426    {
427        de.deserialize_str(AuthorityVisitor)
428    }
429}
430
431/// For `http::Version`
432///
433/// `#[serde(with = "http_serde::version")]`
434pub mod version {
435    use http::Version;
436    use serde::de::{Unexpected, Visitor};
437    use serde::{de, Deserializer, Serializer};
438    use std::fmt::Formatter;
439
440    pub fn serialize<S: Serializer>(version: &Version, ser: S) -> Result<S::Ok, S::Error> {
441        ser.serialize_str(
442            if *version == Version::HTTP_10 { "HTTP/1.0" }
443            else if *version == Version::HTTP_11 { "HTTP/1.1" }
444            else if *version == Version::HTTP_2 { "HTTP/2.0" }
445            else if *version == Version::HTTP_3 { "HTTP/3.0" }
446            else if *version == Version::HTTP_09 { "HTTP/0.9" }
447            else { return Err(serde::ser::Error::custom("http version")) }
448        )
449    }
450
451    pub(crate) struct VersionVisitor;
452
453    impl VersionVisitor {
454        #[inline]
455        pub(crate) fn new<'de, D: Deserializer<'de>>(_: &D) -> Self {
456            Self
457        }
458    }
459
460    impl<'de> Visitor<'de> for VersionVisitor {
461        type Value = Version;
462
463        #[inline]
464        fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
465            formatter.write_str("http version")
466        }
467
468        #[inline]
469        fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
470            deserializer.deserialize_str(self)
471        }
472
473        fn visit_str<E: de::Error>(self, val: &str) -> Result<Self::Value, E> {
474            Ok(match val {
475                "HTTP/1.0" => Version::HTTP_10,
476                "HTTP/1.1" => Version::HTTP_11,
477                "HTTP/2.0" => Version::HTTP_2,
478                "HTTP/3.0" => Version::HTTP_3,
479                "HTTP/0.9" => Version::HTTP_09,
480                _ => Err(de::Error::invalid_value(Unexpected::Str(val), &self))?,
481            })
482        }
483    }
484
485    #[inline]
486    pub fn deserialize<'de, D>(de: D) -> Result<Version, D::Error>
487    where
488        D: Deserializer<'de>,
489    {
490        de.deserialize_str(VersionVisitor)
491    }
492}
493
494/// Serializers and deserializers for types wrapped in `Option`.
495///
496/// ```rust
497/// use http_serde::http;
498/// #[derive(serde::Deserialize)]
499/// struct MaybeUri(#[serde(with = "http_serde::option::uri")] Option<http::Uri>);
500/// ```
501pub mod option {
502    use serde::de;
503    use serde::de::{Deserializer, Visitor};
504    use std::fmt;
505
506    macro_rules! boilerplate {
507        ($mod_name: ident, $item: ty, $visitor: ty) => {
508            /// Use `#[serde(with = "http_serde::option::
509            #[doc = stringify!($mod_name)]
510            ///")]` for `Option<
511            #[doc = stringify!($item)]
512            /// >`
513            pub mod $mod_name {
514                use serde::de::Deserializer;
515                use serde::Serializer;
516
517                struct IsSome<'a>(&'a $item);
518                impl serde::Serialize for IsSome<'_> {
519                    #[inline]
520                    fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
521                        super::super::$mod_name::serialize(self.0, ser)
522                    }
523                }
524
525                pub fn serialize<S: Serializer>(value: &Option<$item>, ser: S) -> Result<S::Ok, S::Error> {
526                    match value.as_ref() {
527                        Some(value) => ser.serialize_some(&IsSome(value)),
528                        None => ser.serialize_none(),
529                    }
530                }
531
532                #[inline]
533                pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<Option<$item>, D::Error> {
534                    let vis = super::OptionVisitor(<$visitor>::new(&de));
535                    de.deserialize_option(vis)
536                }
537            }
538        };
539    }
540
541    boilerplate! { header_map, ::http::HeaderMap, crate::header_map::HeaderMapVisitor }
542    boilerplate! { status_code, ::http::StatusCode, crate::status_code::StatusVisitor }
543    boilerplate! { method, ::http::Method, crate::method::MethodVisitor }
544    boilerplate! { uri, ::http::uri::Uri, crate::uri::UriVisitor }
545    boilerplate! { version, ::http::Version, crate::version::VersionVisitor }
546    boilerplate! { authority, ::http::uri::Authority, crate::authority::AuthorityVisitor }
547
548    struct OptionVisitor<V>(V);
549
550    impl<'de, V> Visitor<'de> for OptionVisitor<V> where V: Visitor<'de> {
551        type Value = Option<V::Value>;
552
553        // Format a message stating what data this Visitor expects to receive.
554        #[inline]
555        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
556            self.0.expecting(formatter)
557        }
558
559        #[inline]
560        fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
561            self.0.visit_some(deserializer).map(Some)
562        }
563
564        #[inline]
565        fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
566            Ok(None)
567        }
568    }
569}