Skip to main content

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