Implement HTTP requests generically for all Endpoints.

This commit is contained in:
Jimmy Cuadra 2017-01-07 05:31:18 -08:00
parent 43d21222dd
commit 6daa7c22f1
3 changed files with 38 additions and 10 deletions

View File

@ -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"

View File

@ -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<HyperError> for Error {
@ -31,3 +34,8 @@ impl From<SerdeJsonError> for Error {
}
}
impl From<SerdeUrlEncodedSerializeError> for Error {
fn from(error: SerdeUrlEncodedSerializeError) -> Error {
Error::SerdeUrlEncodedSerialize(error)
}
}

View File

@ -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<<get_supported_versions::Endpoint as Endpoint>::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<FutureResponse<<get_supported_versions::Endpoint as Endpoint>::Response>, Error> {
self.request::<get_supported_versions::Endpoint>((), (), ())
}
FutureResponse::from(self.hyper.request(request))
fn request<E>(
&mut self,
body_params: E::BodyParams,
path_params: E::PathParams,
query_params: E::QueryParams,
) -> Result<FutureResponse<E::Response>, Error>
where E: Endpoint, <E as 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)))
}
}