From fdc4fa81e5844d2f09c9ebc45a8700e6e3918f4e Mon Sep 17 00:00:00 2001 From: softprops Date: Sun, 25 Nov 2018 20:22:50 +0900 Subject: [PATCH] deserialize http_method directly to http::Method --- src/ext.rs | 12 ++++-------- src/request.rs | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/ext.rs b/src/ext.rs index c3adc6a..1fb7786 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -166,10 +166,9 @@ mod tests { query.insert("foo".to_owned(), "bar".to_owned()); let gwr: GatewayRequest = GatewayRequest { path: "/foo".into(), - http_method: "GET".into(), headers, query_string_parameters: StrMap(query.clone().into()), - ..Default::default() + ..GatewayRequest::default() }; let actual = HttpRequest::from(gwr); assert_eq!( @@ -193,10 +192,9 @@ mod tests { } let gwr: GatewayRequest = GatewayRequest { path: "/foo".into(), - http_method: "GET".into(), headers, body: Some("foo=bar&baz=2".into()), - ..Default::default() + ..GatewayRequest::default() }; let actual = HttpRequest::from(gwr); let payload: Option = actual.payload().unwrap_or_else(|_| None); @@ -219,10 +217,9 @@ mod tests { ); let gwr: GatewayRequest = GatewayRequest { path: "/foo".into(), - http_method: "GET".into(), headers, body: Some("foo=bar&baz=2".into()), - ..Default::default() + ..GatewayRequest::default() }; let actual = HttpRequest::from(gwr); let mut expected = HashMap::new(); @@ -244,10 +241,9 @@ mod tests { } let gwr: GatewayRequest = GatewayRequest { path: "/foo".into(), - http_method: "GET".into(), headers, body: Some(r#"{"foo":"bar", "baz": 2}"#.into()), - ..Default::default() + ..GatewayRequest::default() }; let actual = HttpRequest::from(gwr); let payload: Option = actual.payload().unwrap_or_else(|_| None); diff --git a/src/request.rs b/src/request.rs index b8b0cd7..8d70380 100644 --- a/src/request.rs +++ b/src/request.rs @@ -8,7 +8,7 @@ use std::mem; // Third Party use http::header::{HeaderValue, HOST}; use http::Request as HttpRequest; -use http::{self, HeaderMap}; +use http::{self, HeaderMap, Method}; use serde::{de::Error as DeError, de::MapAccess, de::Visitor, Deserialize, Deserializer}; use body::Body; @@ -25,7 +25,8 @@ use strmap::StrMap; pub struct GatewayRequest<'a> { //pub resDeserializeHeadersource: String, pub(crate) path: Cow<'a, str>, - pub(crate) http_method: Cow<'a, str>, + #[serde(deserialize_with = "deserialize_method")] + pub(crate) http_method: Method, #[serde(deserialize_with = "deserialize_headers")] pub(crate) headers: HeaderMap, #[serde(deserialize_with = "nullable_default")] @@ -73,6 +74,30 @@ pub struct Identity { pub user_arn: Option, } +fn deserialize_method<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + struct MethodVisitor; + + impl<'de> Visitor<'de> for MethodVisitor { + type Value = Method; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a Method") + } + + fn visit_str(self, v: &str) -> Result + where + E: DeError, + { + v.parse().map_err(E::custom) + } + } + + deserializer.deserialize_str(MethodVisitor) +} + fn deserialize_headers<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, @@ -134,7 +159,7 @@ impl<'a> From> for HttpRequest { // build an http::Request from a lando::GatewayRequest let mut builder = HttpRequest::builder(); - builder.method(http_method.as_ref()); + builder.method(http_method); builder.uri({ format!( "https://{}{}", @@ -184,14 +209,14 @@ mod tests { headers.insert("Host", "www.rust-lang.org".parse().unwrap()); let gwr: GatewayRequest = GatewayRequest { path: "/foo".into(), - http_method: "GET".into(), headers, - ..Default::default() + ..GatewayRequest::default() }; let expected = HttpRequest::get("https://www.rust-lang.org/foo") .body(()) .unwrap(); let actual = HttpRequest::from(gwr); + assert_eq!(expected.method(), actual.method()); assert_eq!(expected.uri(), actual.uri()); assert_eq!(expected.method(), actual.method()); } @@ -209,7 +234,7 @@ mod tests { assert_eq!( GatewayRequest { path: "/foo".into(), - ..Default::default() + ..GatewayRequest::default() } .path, "/foo"