Support endpoints with s other than ruma_client_api::Error

This commit is contained in:
Jonas Platte 2020-04-20 13:21:10 +02:00
parent 1b1f8b6341
commit e44087f8b8
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
5 changed files with 31 additions and 32 deletions

View File

@ -31,6 +31,7 @@ serde_urlencoded = "0.6.1"
url = "2.1.1" url = "2.1.1"
[dev-dependencies] [dev-dependencies]
anyhow = "1.0.28"
tokio = { version = "0.2.18", features = ["macros"] } tokio = { version = "0.2.18", features = ["macros"] }
[features] [features]

View File

@ -12,7 +12,7 @@ use ruma_client::{
}; };
use url::Url; use url::Url;
async fn hello_world(homeserver_url: Url, room: String) -> Result<(), ruma_client::Error> { async fn hello_world(homeserver_url: Url, room: String) -> anyhow::Result<()> {
let client = Client::new(homeserver_url, None); let client = Client::new(homeserver_url, None);
client.register_guest().await?; client.register_guest().await?;
@ -49,7 +49,7 @@ async fn hello_world(homeserver_url: Url, room: String) -> Result<(), ruma_clien
} }
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), ruma_client::Error> { async fn main() -> anyhow::Result<()> {
let (homeserver_url, room) = match (env::args().nth(1), env::args().nth(2)) { let (homeserver_url, room) = match (env::args().nth(1), env::args().nth(2)) {
(Some(a), Some(b)) => (a, b), (Some(a), Some(b)) => (a, b),
_ => { _ => {

View File

@ -16,7 +16,7 @@ async fn log_messages(
homeserver_url: Url, homeserver_url: Url,
username: String, username: String,
password: String, password: String,
) -> Result<(), ruma_client::Error> { ) -> anyhow::Result<()> {
let client = HttpClient::new(homeserver_url, None); let client = HttpClient::new(homeserver_url, None);
client.log_in(username, password, None, None).await?; client.log_in(username, password, None, None).await?;
@ -61,7 +61,7 @@ async fn log_messages(
} }
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), ruma_client::Error> { async fn main() -> anyhow::Result<()> {
let (homeserver_url, username, password) = let (homeserver_url, username, password) =
match (env::args().nth(1), env::args().nth(2), env::args().nth(3)) { match (env::args().nth(1), env::args().nth(2), env::args().nth(3)) {
(Some(a), Some(b), Some(c)) => (a, b, c), (Some(a), Some(b), Some(c)) => (a, b, c),

View File

@ -1,16 +1,13 @@
//! Error conditions. //! Error conditions.
use std::error::Error as StdError; use std::fmt::{self, Debug, Display, Formatter};
use std::fmt::{Display, Formatter, Result as FmtResult};
use ruma_api::error::{FromHttpResponseError, IntoHttpError}; use ruma_api::error::{FromHttpResponseError, IntoHttpError};
use crate::api;
/// An error that can occur during client operations. /// An error that can occur during client operations.
#[derive(Debug)] #[derive(Debug)]
#[non_exhaustive] #[non_exhaustive]
pub enum Error { pub enum Error<E> {
/// Queried endpoint requires authentication but was called on an anonymous client. /// Queried endpoint requires authentication but was called on an anonymous client.
AuthenticationRequired, AuthenticationRequired,
/// Construction of the HTTP request failed (this should never happen). /// Construction of the HTTP request failed (this should never happen).
@ -20,11 +17,11 @@ pub enum Error {
/// Couldn't obtain an HTTP response (e.g. due to network or DNS issues). /// Couldn't obtain an HTTP response (e.g. due to network or DNS issues).
Response(ResponseError), Response(ResponseError),
/// Converting the HTTP response to one of ruma's types failed. /// Converting the HTTP response to one of ruma's types failed.
FromHttpResponse(FromHttpResponseError<api::Error>), FromHttpResponse(FromHttpResponseError<E>),
} }
impl Display for Error { impl<E> Display for Error<E> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self { match self {
Self::AuthenticationRequired => { Self::AuthenticationRequired => {
write!(f, "The queried endpoint requires authentication but was called with an anonymous client.") write!(f, "The queried endpoint requires authentication but was called with an anonymous client.")
@ -39,33 +36,33 @@ impl Display for Error {
} }
} }
impl From<IntoHttpError> for Error { impl<E> From<IntoHttpError> for Error<E> {
fn from(err: IntoHttpError) -> Self { fn from(err: IntoHttpError) -> Self {
Error::IntoHttp(err) Error::IntoHttp(err)
} }
} }
#[doc(hidden)] #[doc(hidden)]
impl From<http::uri::InvalidUri> for Error { impl<E> From<http::uri::InvalidUri> for Error<E> {
fn from(err: http::uri::InvalidUri) -> Self { fn from(err: http::uri::InvalidUri) -> Self {
Error::Url(UrlError(err)) Error::Url(UrlError(err))
} }
} }
#[doc(hidden)] #[doc(hidden)]
impl From<hyper::Error> for Error { impl<E> From<hyper::Error> for Error<E> {
fn from(err: hyper::Error) -> Self { fn from(err: hyper::Error) -> Self {
Error::Response(ResponseError(err)) Error::Response(ResponseError(err))
} }
} }
impl From<FromHttpResponseError<api::Error>> for Error { impl<E> From<FromHttpResponseError<E>> for Error<E> {
fn from(err: FromHttpResponseError<api::Error>) -> Self { fn from(err: FromHttpResponseError<E>) -> Self {
Error::FromHttpResponse(err) Error::FromHttpResponse(err)
} }
} }
impl StdError for Error {} impl<E: Debug> std::error::Error for Error<E> {}
#[derive(Debug)] #[derive(Debug)]
pub struct UrlError(http::uri::InvalidUri); pub struct UrlError(http::uri::InvalidUri);

View File

@ -18,7 +18,7 @@
//! //!
//! // You're now logged in! Write the session to a file if you want to restore it later. //! // You're now logged in! Write the session to a file if you want to restore it later.
//! // Then start using the API! //! // Then start using the API!
//! # Result::<(), ruma_client::Error>::Ok(()) //! # Result::<(), ruma_client::Error<_>>::Ok(())
//! }; //! };
//! ``` //! ```
//! //!
@ -59,7 +59,7 @@
//! while let Some(response) = sync_stream.try_next().await? { //! while let Some(response) = sync_stream.try_next().await? {
//! // Do something with the data in the response... //! // Do something with the data in the response...
//! } //! }
//! # Result::<(), ruma_client::Error>::Ok(()) //! # Result::<(), ruma_client::Error<_>>::Ok(())
//! # }; //! # };
//! ``` //! ```
//! //!
@ -91,7 +91,7 @@
//! .await?; //! .await?;
//! //!
//! assert_eq!(response.room_id, RoomId::try_from("!n8f893n9:example.com").unwrap()); //! assert_eq!(response.room_id, RoomId::try_from("!n8f893n9:example.com").unwrap());
//! # Result::<(), ruma_client::Error>::Ok(()) //! # Result::<(), ruma_client::Error<_>>::Ok(())
//! } //! }
//! # ; //! # ;
//! ``` //! ```
@ -224,7 +224,7 @@ where
password: String, password: String,
device_id: Option<DeviceId>, device_id: Option<DeviceId>,
initial_device_display_name: Option<String>, initial_device_display_name: Option<String>,
) -> Result<Session, Error> { ) -> Result<Session, Error<api::Error>> {
use api::r0::session::login; use api::r0::session::login;
let response = self let response = self
@ -251,7 +251,7 @@ where
/// Register as a guest. In contrast to `api::r0::account::register::call()`, /// Register as a guest. In contrast to `api::r0::account::register::call()`,
/// this method stores the session data returned by the endpoint in this /// this method stores the session data returned by the endpoint in this
/// client, instead of returning it. /// client, instead of returning it.
pub async fn register_guest(&self) -> Result<Session, Error> { pub async fn register_guest(&self) -> Result<Session, Error<api::Error>> {
use api::r0::account::register; use api::r0::account::register;
let response = self let response = self
@ -293,7 +293,7 @@ where
&self, &self,
username: Option<String>, username: Option<String>,
password: String, password: String,
) -> Result<Session, Error> { ) -> Result<Session, Error<api::Error>> {
use api::r0::account::register; use api::r0::account::register;
let response = self let response = self
@ -334,8 +334,9 @@ where
since: Option<String>, since: Option<String>,
set_presence: api::r0::sync::sync_events::SetPresence, set_presence: api::r0::sync::sync_events::SetPresence,
timeout: Option<Duration>, timeout: Option<Duration>,
) -> impl Stream<Item = Result<api::r0::sync::sync_events::IncomingResponse, Error>> ) -> impl Stream<Item = Result<api::r0::sync::sync_events::IncomingResponse, Error<api::Error>>>
+ TryStream<Ok = api::r0::sync::sync_events::IncomingResponse, Error = Error> { + TryStream<Ok = api::r0::sync::sync_events::IncomingResponse, Error = Error<api::Error>>
{
use api::r0::sync::sync_events; use api::r0::sync::sync_events;
let client = self.clone(); let client = self.clone();
@ -361,32 +362,32 @@ where
} }
/// Makes a request to a Matrix API endpoint. /// Makes a request to a Matrix API endpoint.
pub fn request<Request: Endpoint<ResponseError = api::Error>>( pub fn request<Request: Endpoint>(
&self, &self,
request: Request, request: Request,
) -> impl Future<Output = Result<<Request::Response as Outgoing>::Incoming, Error>> ) -> impl Future<Output = Result<<Request::Response as Outgoing>::Incoming, Error<Request::ResponseError>>>
// We need to duplicate Endpoint's where clauses because the compiler is not smart enough yet. // We need to duplicate Endpoint's where clauses because the compiler is not smart enough yet.
// See https://github.com/rust-lang/rust/issues/54149 // See https://github.com/rust-lang/rust/issues/54149
where where
Request::Incoming: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>, Request::Incoming: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>,
<Request::Response as Outgoing>::Incoming: <Request::Response as Outgoing>::Incoming:
TryFrom<http::Response<Vec<u8>>, Error = FromHttpResponseError<api::Error>>, TryFrom<http::Response<Vec<u8>>, Error = FromHttpResponseError<Request::ResponseError>>,
{ {
self.request_with_url_params(request, None) self.request_with_url_params(request, None)
} }
/// Makes a request to a Matrix API endpoint including additional URL parameters. /// Makes a request to a Matrix API endpoint including additional URL parameters.
pub fn request_with_url_params<Request: Endpoint<ResponseError = api::Error>>( pub fn request_with_url_params<Request: Endpoint>(
&self, &self,
request: Request, request: Request,
params: Option<BTreeMap<String, String>>, params: Option<BTreeMap<String, String>>,
) -> impl Future<Output = Result<<Request::Response as Outgoing>::Incoming, Error>> ) -> impl Future<Output = Result<<Request::Response as Outgoing>::Incoming, Error<Request::ResponseError>>>
// We need to duplicate Endpoint's where clauses because the compiler is not smart enough yet. // We need to duplicate Endpoint's where clauses because the compiler is not smart enough yet.
// See https://github.com/rust-lang/rust/issues/54149 // See https://github.com/rust-lang/rust/issues/54149
where where
Request::Incoming: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>, Request::Incoming: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>,
<Request::Response as Outgoing>::Incoming: <Request::Response as Outgoing>::Incoming:
TryFrom<http::Response<Vec<u8>>, Error = FromHttpResponseError<api::Error>>, TryFrom<http::Response<Vec<u8>>, Error = FromHttpResponseError<Request::ResponseError>>,
{ {
let client = self.0.clone(); let client = self.0.clone();