From 5d2925c0fa0df220c59b2c102f039863d4b6965c Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Tue, 21 Apr 2020 13:42:51 -0700 Subject: [PATCH] Adding Client, Response traits for reqwest --- src/client/client.rs | 24 ++++++++++++++ src/client/client_reqwest.rs | 63 ++++++++++++++++++++++++++++++++++++ src/client/mod.rs | 7 ++++ src/lib.rs | 2 ++ src/req/mod.rs | 2 +- 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/client/client.rs create mode 100644 src/client/client_reqwest.rs create mode 100644 src/client/mod.rs diff --git a/src/client/client.rs b/src/client/client.rs new file mode 100644 index 0000000..4f92bbb --- /dev/null +++ b/src/client/client.rs @@ -0,0 +1,24 @@ +use std::future::Future; +use std::pin::Pin; + +use serde::de::DeserializeOwned; + +pub type BoxFut = Pin + Send>>; + +pub trait Client where + R: Response, +{ + fn new() -> Self; + fn get(&self, url_base: String, url_path: String, url_query: Option, + headers: Vec<(&'static str, String)>) -> BoxFut>; +} + +// TODO: custom/generic HeaderValue trait? And for keys? +pub trait Response { + fn status_code(&self) -> u16; + fn verison(&self) -> String; + fn header(&self, key: String) -> Option; + fn headers_all(&self, key: String) -> Vec; + fn into_body(self) -> BoxFut>; + fn into_json(self) -> BoxFut>; +} diff --git a/src/client/client_reqwest.rs b/src/client/client_reqwest.rs new file mode 100644 index 0000000..8bc2aeb --- /dev/null +++ b/src/client/client_reqwest.rs @@ -0,0 +1,63 @@ +use std::iter::FromIterator; +use std::convert::TryInto; + +use serde::de::DeserializeOwned; + +use super::{ Client, Response, BoxFut }; + +impl Client for reqwest::Client { + fn new() -> Self { + Self::new() + } + fn get(&self, url_base: String, url_path: String, url_query: Option, + headers: Vec<(&'static str, String)>) -> BoxFut> + { + #[cfg(feature = "nightly")] let url_query = url_query.as_deref(); + #[cfg(not(feature = "nightly"))] let url_query = url_query.as_ref().map(|s| s.as_ref()); + + let mut url = reqwest::Url::parse(&*url_base) + .unwrap_or_else(|_| panic!("Failed to parse url_base: \"{}\".", url_base)); + url.set_path(&*url_path); + url.set_query(url_query); + + let header_iter = headers.into_iter() + .map(|(key, value)| ( + key.try_into().unwrap_or_else(|_| panic!("Invalid header key: \"{}\".", &key)), + // Makes a copy. + (&value).try_into().unwrap_or_else(|_| panic!("Invalid header value: \"{}\".", &value)), + )); + let header_map = reqwest::header::HeaderMap::from_iter(header_iter); + + let fut = self.get(url) + .headers(header_map) + .send(); + return Box::pin(fut); + } +} + +impl Response for reqwest::Response { + fn status_code(&self) -> u16 { + self.status().as_u16() + } + fn verison(&self) -> String { + format!("{:?}", self.version()) + } + fn header(&self, key: String) -> Option { + self.headers().get(key) + .and_then(|value| value.to_str().ok()) + .map(|value| value.to_owned()) + } + fn headers_all(&self, key: String) -> Vec { + self.headers().get_all(key).iter() + .filter_map(|value| value.to_str().ok()) + .map(|value| value.to_owned()) + .collect() + } + fn into_body(self) -> BoxFut> { + //buf: Vec = Vec::with_capacity(self.content_length()); + Box::pin(self.text()) + } + fn into_json(self) -> BoxFut> { + Box::pin(self.json()) + } +} diff --git a/src/client/mod.rs b/src/client/mod.rs new file mode 100644 index 0000000..f222563 --- /dev/null +++ b/src/client/mod.rs @@ -0,0 +1,7 @@ +///! Contains client support for `reqwest` and `surf`. + +mod client; +pub use client::*; + +mod client_reqwest; +pub use client_reqwest::*; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 0ba8e4f..450e258 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,8 @@ /// Re-exported `reqwest` types. pub use reqwest; +pub mod client; + mod config; pub use config::RiotApiConfig; diff --git a/src/req/mod.rs b/src/req/mod.rs index a97e0d1..1fa4877 100644 --- a/src/req/mod.rs +++ b/src/req/mod.rs @@ -1,4 +1,4 @@ -//! Module containing rate limiting and requesting types. +//! Contains rate limiting and requesting types. mod rate_limit; pub use rate_limit::*;