From 6daa7c22f15af985ef215995a78ad504a9b5c0ec Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Sat, 7 Jan 2017 05:31:18 -0800 Subject: [PATCH] Implement HTTP requests generically for all `Endpoint`s. --- Cargo.toml | 1 + src/error.rs | 12 ++++++++++-- src/lib.rs | 35 +++++++++++++++++++++++++++-------- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ad20a3a2..3c756e43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ futures = "0.1.7" ruma-identifiers = "0.6.0" serde = "0.8.21" serde_json = "0.8.4" +serde_urlencoded = "0.3.0" tokio-core = "0.1.3" url = "1.2.4" diff --git a/src/error.rs b/src/error.rs index 8f76a40e..1b30cb6a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,6 @@ use hyper::Error as HyperError; use serde_json::Error as SerdeJsonError; +use serde_urlencoded::ser::Error as SerdeUrlEncodedSerializeError; use url::ParseError; /// An error that occurs during client operations. @@ -9,8 +10,10 @@ pub enum Error { Hyper(HyperError), /// An error when parsing a string as a URL. Url(ParseError), - /// An error when serializing or deserializing a value. - SerdeJson(SerdeJsonError) + /// An error when serializing or deserializing a JSON value. + SerdeJson(SerdeJsonError), + /// An error when serializing a query string value. + SerdeUrlEncodedSerialize(SerdeUrlEncodedSerializeError), } impl From for Error { @@ -31,3 +34,8 @@ impl From for Error { } } +impl From for Error { + fn from(error: SerdeUrlEncodedSerializeError) -> Error { + Error::SerdeUrlEncodedSerialize(error) + } +} diff --git a/src/lib.rs b/src/lib.rs index 2ebd4038..b336661c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,9 +9,12 @@ extern crate ruma_client_api; extern crate ruma_identifiers; extern crate serde; extern crate serde_json; +extern crate serde_urlencoded; extern crate tokio_core; extern crate url; +use std::fmt::Debug; + use hyper::client::{Client as HyperClient, DefaultConnector, Request as HyperRequest}; use hyper::Method as HyperMethod; use ruma_client_api::{Endpoint, Method}; @@ -66,15 +69,31 @@ impl Client { /// Get the versions of the Matrix client-server specification supported by the homeserver. pub fn get_supported_versions(&mut self) - -> FutureResponse<::Response> { - let request = HyperRequest::new( - get_supported_versions::Endpoint::method().into_hyper(), - self.homeserver_url.join( - &get_supported_versions::Endpoint::request_path(()) - ).expect("request path should be joinable").try_into().expect("url should be parsable"), - ); + -> Result::Response>, Error> { + self.request::((), (), ()) + } - FutureResponse::from(self.hyper.request(request)) + fn request( + &mut self, + body_params: E::BodyParams, + path_params: E::PathParams, + query_params: E::QueryParams, + ) -> Result, Error> + where E: Endpoint, ::Response: Debug + Send { + let mut url = self.homeserver_url.join(&E::request_path(path_params))?.try_into()?; + + url.set_query(Some(&serde_urlencoded::to_string(&query_params)?)); + + let mut request = HyperRequest::new(E::method().into_hyper(), url); + + match E::method() { + Method::Post | Method::Put => { + request.set_body(serde_json::to_string(&body_params)?); + } + _ => {} + } + + Ok(FutureResponse::from(self.hyper.request(request))) } }