Skip to content
This repository has been archived by the owner on Dec 14, 2023. It is now read-only.

Commit

Permalink
WIP hyper 0.12
Browse files Browse the repository at this point in the history
  • Loading branch information
Eijebong committed Sep 5, 2018
1 parent 7fba2a2 commit 72d4e44
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 24 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ travis-ci = { repository = "nox/hyper_serde" }
doctest = false

[dependencies]
cookie = {version = "0.10", default-features = false}
hyper = { version = "0.11", features = ["raw_status"] }
cookie = {version = "0.11", default-features = false}
http = "0.1"
hyper = { version = "0.12" }
mime = "0.3"
serde = "1.0"
serde_bytes = "0.10"
time = "0.1"
typed-headers = "0.1"

[dev-dependencies]
serde_test = "1.0"
time = "0.1"

[replace]
"hyper:0.11.2" = { git = "https://github.com/hyperium/hyper.git" }
90 changes: 70 additions & 20 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! The supported types are:
//!
//! * `cookie::Cookie`
//! * `hyper::header::ContentType`
//! * `typed_headers::ContentType`
//! * `hyper::header::Headers`
//! * `hyper::RawStatus`
//! * `hyper::Method`
Expand Down Expand Up @@ -54,25 +54,30 @@
#![deny(unsafe_code)]

extern crate cookie;
extern crate http;
extern crate hyper;
extern crate mime;
extern crate serde;
extern crate serde_bytes;
extern crate time;
extern crate typed_headers;

use cookie::Cookie;
use hyper::header::{ContentType, Headers};
use hyper::RawStatus;
use typed_headers::ContentType;
use hyper::StatusCode;
use hyper::header::{HeaderName, HeaderValue};
use http::HeaderMap;
use hyper::Method;
use mime::Mime;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_bytes::{ByteBuf, Bytes};
use serde::de::{self, MapAccess, SeqAccess, Visitor};
use serde::de::{self, MapAccess, SeqAccess, Visitor, Error};
use serde::ser::{SerializeMap, SerializeSeq};
use std::cmp;
use std::fmt;
use std::ops::{Deref, DerefMut};
use std::str;
use std::str::FromStr;
use time::{Tm, strptime};

/// Deserialises a `T` value with a given deserializer.
Expand Down Expand Up @@ -309,14 +314,15 @@ impl<'a, 'cookie> Serialize for Ser<'a, Cookie<'cookie>> {
}
}

impl<'de> Deserialize<'de> for De<Headers> {

impl<'de> Deserialize<'de> for De<HeaderMap> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,
{
struct HeadersVisitor;

impl<'de> Visitor<'de> for HeadersVisitor {
type Value = De<Headers>;
type Value = De<HeaderMap>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a map from header names to header values")
Expand All @@ -325,17 +331,19 @@ impl<'de> Deserialize<'de> for De<Headers> {
fn visit_unit<E>(self) -> Result<Self::Value, E>
where E: de::Error,
{
Ok(De::new(Headers::new()))
Ok(De::new(HeaderMap::new()))
}

fn visit_map<V>(self,
mut visitor: V)
-> Result<Self::Value, V::Error>
where V: MapAccess<'de>,
{
let mut headers = Headers::new();
while let Some((k, v)) = visitor.next_entry::<String, Value>()? {
headers.set_raw(k, v.0);
let mut headers = HeaderMap::new();
while let Some((k, values)) = visitor.next_entry::<String, Value>()? {
for v in values.0.iter() {
headers.insert(HeaderName::from_str(&k).map_err(V::Error::custom)?, HeaderValue::from_bytes(&v).map_err(V::Error::custom)?);
}
}
Ok(De::new(headers))
}
Expand Down Expand Up @@ -383,7 +391,7 @@ impl<'de> Deserialize<'de> for De<Headers> {
}
}

impl<'a> Serialize for Ser<'a, Headers> {
impl<'a> Serialize for Ser<'a, HeaderMap> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
Expand All @@ -409,10 +417,9 @@ impl<'a> Serialize for Ser<'a, Headers> {
}

let mut serializer = serializer.serialize_map(Some(self.v.len()))?;
for header in self.v.iter() {
let name = header.name();
let value = self.v.get_raw(name).unwrap();
serializer.serialize_entry(name, &Value(&value.iter().map(|v| v.to_vec()).collect::<Vec<Vec<u8>>>(), self.pretty))?;
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().iter().cloned().collect()).collect::<Vec<Vec<u8>>>(), self.pretty))?;
}
serializer.end()
}
Expand Down Expand Up @@ -484,20 +491,63 @@ impl<'a> Serialize for Ser<'a, Mime> {
}
}

impl<'de> Deserialize<'de> for De<RawStatus> {
impl<'de> Deserialize<'de> for De<StatusCode> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,
{
let (code, reason) = Deserialize::deserialize(deserializer)?;
Ok(De::new(RawStatus(code, reason)))
let code = Deserialize::deserialize(deserializer)?;
Ok(De::new(StatusCode::from_u16(code).map_err(D::Error::custom)?))
}
}

impl<'a> Serialize for Ser<'a, StatusCode> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
self.v.as_u16().serialize(serializer)
}
}

impl<'a> Serialize for Ser<'a, RawStatus> {
impl<'a> Serialize for Ser<'a, (StatusCode, String)> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
(self.v.0, &self.v.1).serialize(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<D>(deserializer: D) -> Result<Self, D::Error>
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<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where V: SeqAccess<'de>,
{

let code = visitor.next_element::<u16>()?.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::<String>()?.ok_or_else(||
V::Error::custom("Can't find the reason string")
)?;
Ok((code, reason))
}
}

Expand Down

0 comments on commit 72d4e44

Please sign in to comment.