// Copyright 2023 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! This crate provides wrappers and convenience functions to make Hyper and //! Serde work hand in hand. //! //! The supported types are: //! //! * `cookie::Cookie` //! * `headers_ext::ContentType` //! * `hyper::header::Headers` //! * `hyper::StatusCode` //! * `hyper::Method` //! * `hyper::Uri` //! * `mime::Mime` //! //! # How do I use a data type with a `HeaderMap` member with Serde? //! //! Use the serde attributes `deserialize_with` and `serialize_with`. //! //! ``` //! struct MyStruct { //! #[serde(deserialize_with = "hyper_serde::deserialize", //! serialize_with = "hyper_serde::serialize")] //! headers: HeaderMap, //! } //! ``` //! //! # How do I encode a `HeaderMap` value with `serde_json::to_string`? //! //! Use the `Ser` wrapper. //! //! ``` //! serde_json::to_string(&Ser::new(&headers)) //! ``` //! //! # How do I decode a `Method` value with `serde_json::parse`? //! //! Use the `De` wrapper. //! //! ``` //! serde_json::parse::>("\"PUT\"").map(De::into_inner) //! ``` //! //! # How do I send `Cookie` values as part of an IPC channel? //! //! Use the `Serde` wrapper. It implements `Deref` and `DerefMut` for //! convenience. //! //! ``` //! ipc::channel::>() //! ``` //! //! #![deny(missing_docs)] #![deny(unsafe_code)] use std::ops::{Deref, DerefMut}; use std::str::FromStr; use std::{cmp, fmt, str}; use cookie::Cookie; use headers::ContentType; use http::HeaderMap; use hyper::header::{HeaderName, HeaderValue}; use hyper::{Method, StatusCode, Uri}; use mime::Mime; use serde::de::{self, Error, MapAccess, SeqAccess, Visitor}; use serde::ser::{SerializeMap, SerializeSeq}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_bytes::{ByteBuf, Bytes}; /// Deserialises a `T` value with a given deserializer. /// /// This is useful to deserialize Hyper types used in structure fields or /// tuple members with `#[serde(deserialize_with = "hyper_serde::deserialize")]`. #[inline(always)] pub fn deserialize<'de, T, D>(deserializer: D) -> Result where D: Deserializer<'de>, De: Deserialize<'de>, { De::deserialize(deserializer).map(De::into_inner) } /// Serialises `value` with a given serializer. /// /// This is useful to serialize Hyper types used in structure fields or /// tuple members with `#[serde(serialize_with = "hyper_serde::serialize")]`. #[inline(always)] pub fn serialize(value: &T, serializer: S) -> Result where S: Serializer, for<'a> Ser<'a, T>: Serialize, { Ser::new(value).serialize(serializer) } /// Serialises `value` with a given serializer in a pretty way. /// /// This does the same job as `serialize` but with a prettier format /// for some combinations of types and serialisers. /// /// For now, the only change from `serialize` is when serialising `Headers`, /// where the items in the header values get serialised as strings instead /// of sequences of bytes, if they represent UTF-8 text. #[inline(always)] pub fn serialize_pretty(value: &T, serializer: S) -> Result where S: Serializer, for<'a> Ser<'a, T>: Serialize, { Ser::new_pretty(value).serialize(serializer) } /// A wrapper to deserialize Hyper types. /// /// This is useful with functions such as `serde_json::from_str`. /// /// Values of this type can only be obtained through /// the `serde::Deserialize` trait. #[derive(Debug, PartialEq)] pub struct De { v: T, } impl De { /// Returns a new `De` wrapper #[inline(always)] pub fn new(v: T) -> Self { De { v } } } impl<'de, T> De where De: Deserialize<'de>, { /// Consumes this wrapper, returning the deserialized value. #[inline(always)] pub fn into_inner(self) -> T { self.v } } /// A wrapper to serialize Hyper types. /// /// This is useful with functions such as `serde_json::to_string`. /// /// Values of this type can only be passed to the `serde::Serialize` trait. #[derive(Debug)] pub struct Ser<'a, T: 'a> { v: &'a T, pretty: bool, } impl<'a, T> Ser<'a, T> where Ser<'a, T>: serde::Serialize, { /// Returns a new `Ser` wrapper. #[inline(always)] pub fn new(value: &'a T) -> Self { Ser { v: value, pretty: false, } } /// Returns a new `Ser` wrapper, in pretty mode. /// /// See `serialize_pretty`. #[inline(always)] pub fn new_pretty(value: &'a T) -> Self { Ser { v: value, pretty: true, } } } /// A convenience wrapper to be used as a type parameter, for example when /// a `Vec` need to be passed to serde. #[derive(Clone, PartialEq)] pub struct Serde(pub T) where for<'de> De: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize; impl Serde where for<'de> De: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize, { /// Consumes this wrapper, returning the inner value. #[inline(always)] pub fn into_inner(self) -> T { self.0 } } impl fmt::Debug for Serde where T: fmt::Debug, for<'de> De: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize, { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { self.0.fmt(formatter) } } impl Deref for Serde where for<'de> De: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize, { type Target = T; fn deref(&self) -> &T { &self.0 } } impl DerefMut for Serde where for<'de> De: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize, { fn deref_mut(&mut self) -> &mut T { &mut self.0 } } impl PartialEq for Serde where for<'de> De: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize, { fn eq(&self, other: &T) -> bool { self.0 == *other } } impl<'b, T> Deserialize<'b> for Serde where for<'de> De: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize, { fn deserialize(deserializer: D) -> Result where D: Deserializer<'b>, { De::deserialize(deserializer).map(De::into_inner).map(Serde) } } impl Serialize for Serde where for<'de> De: Deserialize<'de>, for<'a> Ser<'a, T>: Serialize, { fn serialize(&self, serializer: S) -> Result where S: Serializer, { Ser::new(&self.0).serialize(serializer) } } impl<'de> Deserialize<'de> for De { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserialize(deserializer) .map(|v: mime::Mime| ContentType::from(v)) .map(De::new) } } impl Serialize for Ser<'_, ContentType> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serialize(&mime::Mime::from(self.v.clone()), serializer) } } impl<'de> Deserialize<'de> for De> { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct CookieVisitor; impl Visitor<'_> for CookieVisitor { type Value = De>; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "an HTTP cookie header value") } fn visit_str(self, v: &str) -> Result where E: de::Error, { Cookie::parse(v) .map(Cookie::into_owned) .map(De::new) .map_err(|e| E::custom(format!("{:?}", e))) } } deserializer.deserialize_string(CookieVisitor) } } impl Serialize for Ser<'_, Cookie<'_>> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(&self.v.to_string()) } } impl<'de> Deserialize<'de> for De { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct HeadersVisitor; impl<'de> Visitor<'de> for HeadersVisitor { type Value = De; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "a map from header names to header values") } fn visit_unit(self) -> Result where E: de::Error, { Ok(De::new(HeaderMap::new())) } fn visit_map(self, mut visitor: V) -> Result where V: MapAccess<'de>, { let mut headers = HeaderMap::new(); while let Some((k, values)) = visitor.next_entry::()? { for v in values.0.iter() { headers.append( HeaderName::from_str(&k).map_err(V::Error::custom)?, HeaderValue::from_bytes(v).map_err(V::Error::custom)?, ); } } Ok(De::new(headers)) } } struct Value(Vec>); impl<'de> Deserialize<'de> for Value { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_seq(ValueVisitor) } } struct ValueVisitor; impl<'de> Visitor<'de> for ValueVisitor { type Value = Value; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "an array of strings and sequences of bytes") } fn visit_unit(self) -> Result where E: de::Error, { Ok(Value(vec![])) } fn visit_seq(self, mut visitor: V) -> Result where V: SeqAccess<'de>, { // Clamp to not OOM on rogue values. let capacity = cmp::min(visitor.size_hint().unwrap_or(0), 64); let mut values = Vec::with_capacity(capacity); while let Some(v) = visitor.next_element::()? { values.push(v.into_vec()); } Ok(Value(values)) } } deserializer.deserialize_map(HeadersVisitor) } } impl Serialize for Ser<'_, HeaderMap> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { struct Value<'headers>(&'headers [Vec], bool); impl Serialize for Value<'_> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { let mut serializer = serializer.serialize_seq(Some(self.0.len()))?; for v in self.0 { if self.1 { if let Ok(v) = str::from_utf8(v) { serializer.serialize_element(v)?; continue; } } serializer.serialize_element(&Bytes::new(v))?; } serializer.end() } } let mut serializer = serializer.serialize_map(Some(self.v.keys_len()))?; for name in self.v.keys() { let values = self.v.get_all(name); serializer.serialize_entry( name.as_str(), &Value( &values .iter() .map(|v| v.as_bytes().to_vec()) .collect::>>(), self.pretty, ), )?; } serializer.end() } } impl<'de> Deserialize<'de> for De { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct MethodVisitor; impl Visitor<'_> for MethodVisitor { type Value = De; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "an HTTP method") } fn visit_str(self, v: &str) -> Result where E: de::Error, { v.parse::().map(De::new).map_err(E::custom) } } deserializer.deserialize_string(MethodVisitor) } } impl Serialize for Ser<'_, Method> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { Serialize::serialize(self.v.as_ref(), serializer) } } impl<'de> Deserialize<'de> for De { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct MimeVisitor; impl Visitor<'_> for MimeVisitor { type Value = De; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "a mime type") } fn visit_str(self, v: &str) -> Result where E: de::Error, { v.parse::() .map(De::new) .map_err(|_| E::custom("could not parse mime type")) } } deserializer.deserialize_string(MimeVisitor) } } impl Serialize for Ser<'_, Mime> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(self.v.as_ref()) } } impl<'de> Deserialize<'de> for De { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { let code = Deserialize::deserialize(deserializer)?; Ok(De::new( StatusCode::from_u16(code).map_err(D::Error::custom)?, )) } } impl Serialize for Ser<'_, StatusCode> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { self.v.as_u16().serialize(serializer) } } impl Serialize for Ser<'_, (StatusCode, String)> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { let mut serializer = serializer.serialize_seq(Some(2))?; serializer.serialize_element(&Ser::new(&self.v.0))?; serializer.serialize_element(&self.v.1)?; serializer.end() } } impl<'de> Deserialize<'de> for De<(StatusCode, String)> { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { Ok(De::new(deserializer.deserialize_seq(StatusVisitor)?)) } } struct StatusVisitor; impl<'de> Visitor<'de> for StatusVisitor { type Value = (StatusCode, String); fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!( formatter, "an array containing a status code and a reason string" ) } fn visit_seq(self, mut visitor: V) -> Result where V: SeqAccess<'de>, { let code = visitor .next_element::()? .ok_or_else(|| V::Error::custom("Can't find the status code"))?; let code = StatusCode::from_u16(code).map_err(V::Error::custom)?; let reason = visitor .next_element::()? .ok_or_else(|| V::Error::custom("Can't find the reason string"))?; Ok((code, reason)) } } impl<'de> Deserialize<'de> for De { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct UriVisitor; impl Visitor<'_> for UriVisitor { type Value = De; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "an HTTP Uri value") } fn visit_str(self, v: &str) -> Result where E: de::Error, { Uri::from_str(v) .map(De::new) .map_err(|e| E::custom(format!("{}", e))) } } deserializer.deserialize_string(UriVisitor) } } impl Serialize for Ser<'_, Uri> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { // As of hyper 0.12, hyper::Uri (re-exported http::Uri) // does not implement as_ref due to underlying implementation // so we must construct a string to serialize it serializer.serialize_str(&self.v.to_string()) } }