hyper_serde/
lib.rs

1// Copyright 2023 The Servo Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! This crate provides wrappers and convenience functions to make Hyper and
12//! Serde work hand in hand.
13//!
14//! The supported types are:
15//!
16//! * `cookie::Cookie`
17//! * `headers_ext::ContentType`
18//! * `hyper::header::Headers`
19//! * `hyper::StatusCode`
20//! * `hyper::Method`
21//! * `hyper::Uri`
22//! * `mime::Mime`
23//!
24//! # How do I use a data type with a `HeaderMap` member with Serde?
25//!
26//! Use the serde attributes `deserialize_with` and `serialize_with`.
27//!
28//! ```
29//! struct MyStruct {
30//! #[serde(deserialize_with = "hyper_serde::deserialize",
31//! serialize_with = "hyper_serde::serialize")]
32//! headers: HeaderMap,
33//! }
34//! ```
35//!
36//! # How do I encode a `HeaderMap` value with `serde_json::to_string`?
37//!
38//! Use the `Ser` wrapper.
39//!
40//! ```
41//! serde_json::to_string(&Ser::new(&headers))
42//! ```
43//!
44//! # How do I decode a `Method` value with `serde_json::parse`?
45//!
46//! Use the `De` wrapper.
47//!
48//! ```
49//! serde_json::parse::<De<Method>>("\"PUT\"").map(De::into_inner)
50//! ```
51//!
52//! # How do I send `Cookie` values as part of an IPC channel?
53//!
54//! Use the `Serde` wrapper. It implements `Deref` and `DerefMut` for
55//! convenience.
56//!
57//! ```
58//! ipc::channel::<Serde<Cookie>>()
59//! ```
60//!
61//!
62
63#![deny(missing_docs)]
64#![deny(unsafe_code)]
65
66use std::ops::{Deref, DerefMut};
67use std::str::FromStr;
68use std::{cmp, fmt, str};
69
70use cookie::Cookie;
71use headers::ContentType;
72use http::HeaderMap;
73use hyper::header::{HeaderName, HeaderValue};
74use hyper::{Method, StatusCode, Uri};
75use mime::Mime;
76use serde::de::{self, Error, MapAccess, SeqAccess, Visitor};
77use serde::ser::{SerializeMap, SerializeSeq};
78use serde::{Deserialize, Deserializer, Serialize, Serializer};
79use serde_bytes::{ByteBuf, Bytes};
80
81/// Deserialises a `T` value with a given deserializer.
82///
83/// This is useful to deserialize Hyper types used in structure fields or
84/// tuple members with `#[serde(deserialize_with = "hyper_serde::deserialize")]`.
85#[inline(always)]
86pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
87where
88    D: Deserializer<'de>,
89    De<T>: Deserialize<'de>,
90{
91    De::deserialize(deserializer).map(De::into_inner)
92}
93
94/// Serialises `value` with a given serializer.
95///
96/// This is useful to serialize Hyper types used in structure fields or
97/// tuple members with `#[serde(serialize_with = "hyper_serde::serialize")]`.
98#[inline(always)]
99pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
100where
101    S: Serializer,
102    for<'a> Ser<'a, T>: Serialize,
103{
104    Ser::new(value).serialize(serializer)
105}
106
107/// Serialises `value` with a given serializer in a pretty way.
108///
109/// This does the same job as `serialize` but with a prettier format
110/// for some combinations of types and serialisers.
111///
112/// For now, the only change from `serialize` is when serialising `Headers`,
113/// where the items in the header values get serialised as strings instead
114/// of sequences of bytes, if they represent UTF-8 text.
115#[inline(always)]
116pub fn serialize_pretty<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
117where
118    S: Serializer,
119    for<'a> Ser<'a, T>: Serialize,
120{
121    Ser::new_pretty(value).serialize(serializer)
122}
123
124/// A wrapper to deserialize Hyper types.
125///
126/// This is useful with functions such as `serde_json::from_str`.
127///
128/// Values of this type can only be obtained through
129/// the `serde::Deserialize` trait.
130#[derive(Debug, PartialEq)]
131pub struct De<T> {
132    v: T,
133}
134
135impl<T> De<T> {
136    /// Returns a new `De` wrapper
137    #[inline(always)]
138    pub fn new(v: T) -> Self {
139        De { v }
140    }
141}
142
143impl<'de, T> De<T>
144where
145    De<T>: Deserialize<'de>,
146{
147    /// Consumes this wrapper, returning the deserialized value.
148    #[inline(always)]
149    pub fn into_inner(self) -> T {
150        self.v
151    }
152}
153
154/// A wrapper to serialize Hyper types.
155///
156/// This is useful with functions such as `serde_json::to_string`.
157///
158/// Values of this type can only be passed to the `serde::Serialize` trait.
159#[derive(Debug)]
160pub struct Ser<'a, T: 'a> {
161    v: &'a T,
162    pretty: bool,
163}
164
165impl<'a, T> Ser<'a, T>
166where
167    Ser<'a, T>: serde::Serialize,
168{
169    /// Returns a new `Ser` wrapper.
170    #[inline(always)]
171    pub fn new(value: &'a T) -> Self {
172        Ser {
173            v: value,
174            pretty: false,
175        }
176    }
177
178    /// Returns a new `Ser` wrapper, in pretty mode.
179    ///
180    /// See `serialize_pretty`.
181    #[inline(always)]
182    pub fn new_pretty(value: &'a T) -> Self {
183        Ser {
184            v: value,
185            pretty: true,
186        }
187    }
188}
189
190/// A convenience wrapper to be used as a type parameter, for example when
191/// a `Vec<T>` need to be passed to serde.
192#[derive(Clone, PartialEq)]
193pub struct Serde<T>(pub T)
194where
195    for<'de> De<T>: Deserialize<'de>,
196    for<'a> Ser<'a, T>: Serialize;
197
198impl<T> Serde<T>
199where
200    for<'de> De<T>: Deserialize<'de>,
201    for<'a> Ser<'a, T>: Serialize,
202{
203    /// Consumes this wrapper, returning the inner value.
204    #[inline(always)]
205    pub fn into_inner(self) -> T {
206        self.0
207    }
208}
209
210impl<T> fmt::Debug for Serde<T>
211where
212    T: fmt::Debug,
213    for<'de> De<T>: Deserialize<'de>,
214    for<'a> Ser<'a, T>: Serialize,
215{
216    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
217        self.0.fmt(formatter)
218    }
219}
220
221impl<T> Deref for Serde<T>
222where
223    for<'de> De<T>: Deserialize<'de>,
224    for<'a> Ser<'a, T>: Serialize,
225{
226    type Target = T;
227
228    fn deref(&self) -> &T {
229        &self.0
230    }
231}
232
233impl<T> DerefMut for Serde<T>
234where
235    for<'de> De<T>: Deserialize<'de>,
236    for<'a> Ser<'a, T>: Serialize,
237{
238    fn deref_mut(&mut self) -> &mut T {
239        &mut self.0
240    }
241}
242
243impl<T: PartialEq> PartialEq<T> for Serde<T>
244where
245    for<'de> De<T>: Deserialize<'de>,
246    for<'a> Ser<'a, T>: Serialize,
247{
248    fn eq(&self, other: &T) -> bool {
249        self.0 == *other
250    }
251}
252
253impl<'b, T> Deserialize<'b> for Serde<T>
254where
255    for<'de> De<T>: Deserialize<'de>,
256    for<'a> Ser<'a, T>: Serialize,
257{
258    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
259    where
260        D: Deserializer<'b>,
261    {
262        De::deserialize(deserializer).map(De::into_inner).map(Serde)
263    }
264}
265
266impl<T> Serialize for Serde<T>
267where
268    for<'de> De<T>: Deserialize<'de>,
269    for<'a> Ser<'a, T>: Serialize,
270{
271    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
272    where
273        S: Serializer,
274    {
275        Ser::new(&self.0).serialize(serializer)
276    }
277}
278
279impl<'de> Deserialize<'de> for De<ContentType> {
280    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
281    where
282        D: Deserializer<'de>,
283    {
284        deserialize(deserializer)
285            .map(|v: mime::Mime| ContentType::from(v))
286            .map(De::new)
287    }
288}
289
290impl Serialize for Ser<'_, ContentType> {
291    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
292    where
293        S: Serializer,
294    {
295        serialize(&mime::Mime::from(self.v.clone()), serializer)
296    }
297}
298
299impl<'de> Deserialize<'de> for De<Cookie<'static>> {
300    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
301    where
302        D: Deserializer<'de>,
303    {
304        struct CookieVisitor;
305
306        impl Visitor<'_> for CookieVisitor {
307            type Value = De<Cookie<'static>>;
308
309            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
310                write!(formatter, "an HTTP cookie header value")
311            }
312
313            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
314            where
315                E: de::Error,
316            {
317                Cookie::parse(v)
318                    .map(Cookie::into_owned)
319                    .map(De::new)
320                    .map_err(|e| E::custom(format!("{:?}", e)))
321            }
322        }
323
324        deserializer.deserialize_string(CookieVisitor)
325    }
326}
327
328impl Serialize for Ser<'_, Cookie<'_>> {
329    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
330    where
331        S: Serializer,
332    {
333        serializer.serialize_str(&self.v.to_string())
334    }
335}
336
337impl<'de> Deserialize<'de> for De<HeaderMap> {
338    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
339    where
340        D: Deserializer<'de>,
341    {
342        struct HeadersVisitor;
343
344        impl<'de> Visitor<'de> for HeadersVisitor {
345            type Value = De<HeaderMap>;
346
347            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
348                write!(formatter, "a map from header names to header values")
349            }
350
351            fn visit_unit<E>(self) -> Result<Self::Value, E>
352            where
353                E: de::Error,
354            {
355                Ok(De::new(HeaderMap::new()))
356            }
357
358            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
359            where
360                V: MapAccess<'de>,
361            {
362                let mut headers = HeaderMap::new();
363                while let Some((k, values)) = visitor.next_entry::<String, Value>()? {
364                    for v in values.0.iter() {
365                        headers.append(
366                            HeaderName::from_str(&k).map_err(V::Error::custom)?,
367                            HeaderValue::from_bytes(v).map_err(V::Error::custom)?,
368                        );
369                    }
370                }
371                Ok(De::new(headers))
372            }
373        }
374
375        struct Value(Vec<Vec<u8>>);
376
377        impl<'de> Deserialize<'de> for Value {
378            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
379            where
380                D: Deserializer<'de>,
381            {
382                deserializer.deserialize_seq(ValueVisitor)
383            }
384        }
385
386        struct ValueVisitor;
387
388        impl<'de> Visitor<'de> for ValueVisitor {
389            type Value = Value;
390
391            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
392                write!(formatter, "an array of strings and sequences of bytes")
393            }
394
395            fn visit_unit<E>(self) -> Result<Value, E>
396            where
397                E: de::Error,
398            {
399                Ok(Value(vec![]))
400            }
401
402            fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
403            where
404                V: SeqAccess<'de>,
405            {
406                // Clamp to not OOM on rogue values.
407                let capacity = cmp::min(visitor.size_hint().unwrap_or(0), 64);
408                let mut values = Vec::with_capacity(capacity);
409                while let Some(v) = visitor.next_element::<ByteBuf>()? {
410                    values.push(v.into_vec());
411                }
412                Ok(Value(values))
413            }
414        }
415
416        deserializer.deserialize_map(HeadersVisitor)
417    }
418}
419
420impl Serialize for Ser<'_, HeaderMap> {
421    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
422    where
423        S: Serializer,
424    {
425        struct Value<'headers>(&'headers [Vec<u8>], bool);
426
427        impl Serialize for Value<'_> {
428            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
429            where
430                S: Serializer,
431            {
432                let mut serializer = serializer.serialize_seq(Some(self.0.len()))?;
433                for v in self.0 {
434                    #[allow(
435                        clippy::collapsible_if,
436                        reason = "let chains are not available in 1.85"
437                    )]
438                    if self.1 {
439                        if let Ok(v) = str::from_utf8(v) {
440                            serializer.serialize_element(v)?;
441                            continue;
442                        }
443                    }
444                    serializer.serialize_element(&Bytes::new(v))?;
445                }
446                serializer.end()
447            }
448        }
449
450        let mut serializer = serializer.serialize_map(Some(self.v.keys_len()))?;
451        for name in self.v.keys() {
452            let values = self.v.get_all(name);
453            serializer.serialize_entry(
454                name.as_str(),
455                &Value(
456                    &values
457                        .iter()
458                        .map(|v| v.as_bytes().to_vec())
459                        .collect::<Vec<Vec<u8>>>(),
460                    self.pretty,
461                ),
462            )?;
463        }
464        serializer.end()
465    }
466}
467
468impl<'de> Deserialize<'de> for De<Method> {
469    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
470    where
471        D: Deserializer<'de>,
472    {
473        struct MethodVisitor;
474
475        impl Visitor<'_> for MethodVisitor {
476            type Value = De<Method>;
477
478            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
479                write!(formatter, "an HTTP method")
480            }
481
482            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
483            where
484                E: de::Error,
485            {
486                v.parse::<Method>().map(De::new).map_err(E::custom)
487            }
488        }
489
490        deserializer.deserialize_string(MethodVisitor)
491    }
492}
493
494impl Serialize for Ser<'_, Method> {
495    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
496    where
497        S: Serializer,
498    {
499        Serialize::serialize(self.v.as_ref(), serializer)
500    }
501}
502
503impl<'de> Deserialize<'de> for De<Mime> {
504    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
505    where
506        D: Deserializer<'de>,
507    {
508        struct MimeVisitor;
509
510        impl Visitor<'_> for MimeVisitor {
511            type Value = De<Mime>;
512
513            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
514                write!(formatter, "a mime type")
515            }
516
517            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
518            where
519                E: de::Error,
520            {
521                v.parse::<Mime>()
522                    .map(De::new)
523                    .map_err(|_| E::custom("could not parse mime type"))
524            }
525        }
526
527        deserializer.deserialize_string(MimeVisitor)
528    }
529}
530
531impl Serialize for Ser<'_, Mime> {
532    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
533    where
534        S: Serializer,
535    {
536        serializer.serialize_str(self.v.as_ref())
537    }
538}
539
540impl<'de> Deserialize<'de> for De<StatusCode> {
541    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
542    where
543        D: Deserializer<'de>,
544    {
545        let code = Deserialize::deserialize(deserializer)?;
546        Ok(De::new(
547            StatusCode::from_u16(code).map_err(D::Error::custom)?,
548        ))
549    }
550}
551
552impl Serialize for Ser<'_, StatusCode> {
553    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
554    where
555        S: Serializer,
556    {
557        self.v.as_u16().serialize(serializer)
558    }
559}
560
561impl Serialize for Ser<'_, (StatusCode, String)> {
562    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
563    where
564        S: Serializer,
565    {
566        let mut serializer = serializer.serialize_seq(Some(2))?;
567        serializer.serialize_element(&Ser::new(&self.v.0))?;
568        serializer.serialize_element(&self.v.1)?;
569        serializer.end()
570    }
571}
572
573impl<'de> Deserialize<'de> for De<(StatusCode, String)> {
574    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
575    where
576        D: Deserializer<'de>,
577    {
578        Ok(De::new(deserializer.deserialize_seq(StatusVisitor)?))
579    }
580}
581
582struct StatusVisitor;
583
584impl<'de> Visitor<'de> for StatusVisitor {
585    type Value = (StatusCode, String);
586
587    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
588        write!(
589            formatter,
590            "an array containing a status code and a reason string"
591        )
592    }
593
594    fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
595    where
596        V: SeqAccess<'de>,
597    {
598        let code = visitor
599            .next_element::<u16>()?
600            .ok_or_else(|| V::Error::custom("Can't find the status code"))?;
601        let code = StatusCode::from_u16(code).map_err(V::Error::custom)?;
602        let reason = visitor
603            .next_element::<String>()?
604            .ok_or_else(|| V::Error::custom("Can't find the reason string"))?;
605        Ok((code, reason))
606    }
607}
608
609impl<'de> Deserialize<'de> for De<Uri> {
610    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
611    where
612        D: Deserializer<'de>,
613    {
614        struct UriVisitor;
615
616        impl Visitor<'_> for UriVisitor {
617            type Value = De<Uri>;
618
619            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
620                write!(formatter, "an HTTP Uri value")
621            }
622
623            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
624            where
625                E: de::Error,
626            {
627                Uri::from_str(v)
628                    .map(De::new)
629                    .map_err(|e| E::custom(format!("{}", e)))
630            }
631        }
632
633        deserializer.deserialize_string(UriVisitor)
634    }
635}
636
637impl Serialize for Ser<'_, Uri> {
638    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
639    where
640        S: Serializer,
641    {
642        // As of hyper 0.12, hyper::Uri (re-exported http::Uri)
643        // does not implement as_ref due to underlying implementation
644        // so we must construct a string to serialize it
645        serializer.serialize_str(&self.v.to_string())
646    }
647}