Update dependencies, use published ruma crates, add new Client constructors.

This commit is contained in:
Jimmy Cuadra 2017-07-07 23:19:12 -07:00
parent b6f0d8d8b4
commit 86e837d26f
3 changed files with 72 additions and 40 deletions

View File

@ -11,21 +11,25 @@ repository = "https://github.com/ruma/ruma-client"
version = "0.1.0" version = "0.1.0"
[dependencies] [dependencies]
futures = "0.1.13" futures = "0.1.14"
hyper = "0.11.1"
ruma-api = "0.4.0"
ruma-client-api = "0.1.0"
ruma-identifiers = "0.11.0" ruma-identifiers = "0.11.0"
serde = "1.0.2" serde = "1.0.9"
serde_json = "1.0.1" serde_json = "1.0.2"
serde_urlencoded = "0.4.3" serde_urlencoded = "0.5.1"
tokio-core = "0.1.6" tokio-core = "0.1.8"
url = "1.4.0" url = "1.5.1"
[dependencies.hyper] [dependencies.hyper-tls]
git = "https://github.com/hyperium/hyper" optional = true
rev = "fed04dfb58e19b408322d4e5ca7474871e848a35" version = "0.1.2"
[dependencies.ruma-api] [dependencies.native-tls]
git = "https://github.com/ruma/ruma-api" optional = true
version = "0.1.4"
[dependencies.ruma-client-api] [features]
git = "https://github.com/ruma/ruma-client-api" default = ["tls"]
branch = "manual" tls = ["hyper-tls", "native-tls"]

View File

@ -1,5 +1,5 @@
use hyper::Error as HyperError; use hyper::Error as HyperError;
use ruma_client_api::Error as RumaClientApiError; use ruma_api::Error as RumaApiError;
use serde_json::Error as SerdeJsonError; use serde_json::Error as SerdeJsonError;
use serde_urlencoded::ser::Error as SerdeUrlEncodedSerializeError; use serde_urlencoded::ser::Error as SerdeUrlEncodedSerializeError;
use url::ParseError; use url::ParseError;
@ -7,18 +7,18 @@ use url::ParseError;
/// An error that occurs during client operations. /// An error that occurs during client operations.
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
/// Queried endpoint requires authentication but was called on an anonymous client
AuthenticationRequired,
/// An error at the HTTP layer. /// An error at the HTTP layer.
Hyper(HyperError), Hyper(HyperError),
/// An error when parsing a string as a URL. /// An error when parsing a string as a URL.
Url(ParseError), Url(ParseError),
/// An error converting between ruma_client_api types and Hyper types. /// An error converting between ruma_client_api types and Hyper types.
RumaClientApi(RumaClientApiError), RumaApi(RumaApiError),
/// An error when serializing or deserializing a JSON value. /// An error when serializing or deserializing a JSON value.
SerdeJson(SerdeJsonError), SerdeJson(SerdeJsonError),
/// An error when serializing a query string value. /// An error when serializing a query string value.
SerdeUrlEncodedSerialize(SerdeUrlEncodedSerializeError), SerdeUrlEncodedSerialize(SerdeUrlEncodedSerializeError),
/// Queried endpoint requires authentication but was called on an anonymous client
AuthenticationRequired,
} }
impl From<HyperError> for Error { impl From<HyperError> for Error {
@ -33,9 +33,9 @@ impl From<ParseError> for Error {
} }
} }
impl From<RumaClientApiError> for Error { impl From<RumaApiError> for Error {
fn from(error: RumaClientApiError) -> Error { fn from(error: RumaApiError) -> Error {
Error::RumaClientApi(error) Error::RumaApi(error)
} }
} }

View File

@ -6,8 +6,10 @@
extern crate futures; extern crate futures;
extern crate hyper; extern crate hyper;
#[cfg(feature = "tls")] extern crate hyper_tls;
#[cfg(feature = "tls")] extern crate native_tls;
extern crate ruma_api; extern crate ruma_api;
pub extern crate ruma_client_api; extern crate ruma_client_api;
extern crate ruma_identifiers; extern crate ruma_identifiers;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
@ -15,11 +17,14 @@ extern crate serde_urlencoded;
extern crate tokio_core; extern crate tokio_core;
extern crate url; extern crate url;
use std::convert::{TryFrom, TryInto}; use std::convert::TryInto;
use std::rc::Rc;
use futures::{Future, IntoFuture}; use futures::future::{Future, FutureFrom, IntoFuture};
use hyper::{Client as HyperClient, Request as HyperRequest, Response as HyperResponse}; use hyper::{Client as HyperClient};
use hyper::client::HttpConnector; use hyper::client::{Connect, HttpConnector};
#[cfg(feature = "hyper-tls")] use hyper_tls::HttpsConnector;
#[cfg(feature = "hyper-tls")] use native_tls::Error as NativeTlsError;
use ruma_api::Endpoint; use ruma_api::Endpoint;
use tokio_core::reactor::Handle; use tokio_core::reactor::Handle;
use url::Url; use url::Url;
@ -32,40 +37,63 @@ mod session;
/// A client for the Matrix client-server API. /// A client for the Matrix client-server API.
#[derive(Debug)] #[derive(Debug)]
pub struct Client { pub struct Client<C> where C: Connect {
homeserver_url: Url, homeserver_url: Url,
hyper: HyperClient<HttpConnector>, hyper: Rc<HyperClient<C>>,
session: Option<Session>, session: Option<Session>,
} }
impl Client { impl Client<HttpConnector> {
/// Creates a new client for making requests to the given homeserver. /// Creates a new client for making HTTP requests to the given homeserver.
pub fn new(handle: &Handle, homeserver_url: Url) -> Self { pub fn new(handle: &Handle, homeserver_url: Url) -> Self {
Client { Client {
homeserver_url, homeserver_url,
hyper: HyperClient::configure().keep_alive(true).build(handle), hyper: Rc::new(HyperClient::configure().keep_alive(true).build(handle)),
session: None,
}
}
}
#[cfg(feature = "tls")]
impl Client<HttpsConnector<HttpConnector>> {
/// Creates a new client for making HTTPS requests to the given homeserver.
pub fn https(handle: &Handle, homeserver_url: Url) -> Result<Self, NativeTlsError> {
let connector = HttpsConnector::new(4, handle)?;
Ok(Client {
homeserver_url,
hyper: Rc::new(HyperClient::configure().connector(connector).keep_alive(true).build(handle)),
session: None,
})
}
}
impl<C> Client<C> where C: Connect {
/// Creates a new client using the given `hyper::Client`.
///
/// This allows the user to configure the details of HTTP as desired.
pub fn custom(hyper_client: HyperClient<C>, homeserver_url: Url) -> Self {
Client {
homeserver_url,
hyper: Rc::new(hyper_client),
session: None, session: None,
} }
} }
/// Makes a request to a Matrix API endpoint. /// Makes a request to a Matrix API endpoint.
pub fn request<E>(&self, request: <E as Endpoint>::Request) pub(crate) fn request<'a, E>(&'a self, request: <E as Endpoint>::Request)
-> impl Future<Item = E::Response, Error = Error> -> impl Future<Item = E::Response, Error = Error> + 'a
where E: Endpoint, where E: Endpoint,
E::Response: 'static, <E as Endpoint>::Response: 'a {
Error: From<<E::Request as TryInto<HyperRequest>>::Error>,
Error: From<<E::Response as TryFrom<HyperResponse>>::Error> {
let cloned_hyper = self.hyper.clone();
request request
.try_into() .try_into()
.map_err(Error::from) .map_err(Error::from)
.into_future() .into_future()
.and_then(move |hyper_request| { .and_then(move |hyper_request| {
cloned_hyper.request(hyper_request).map_err(Error::from) self.hyper.clone().request(hyper_request).map_err(Error::from)
}) })
.and_then(|hyper_response| { .and_then(|hyper_response| {
hyper_response.try_into().map_err(Error::from) E::Response::future_from(hyper_response).map_err(Error::from)
}) })
} }
} }