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"
[dev-dependencies]
anyhow = "1.0.28"
tokio = { version = "0.2.18", features = ["macros"] }
[features]

View File

@ -12,7 +12,7 @@ use ruma_client::{
};
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);
client.register_guest().await?;
@ -49,7 +49,7 @@ async fn hello_world(homeserver_url: Url, room: String) -> Result<(), ruma_clien
}
#[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)) {
(Some(a), Some(b)) => (a, b),
_ => {

View File

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

View File

@ -1,16 +1,13 @@
//! Error conditions.
use std::error::Error as StdError;
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::fmt::{self, Debug, Display, Formatter};
use ruma_api::error::{FromHttpResponseError, IntoHttpError};
use crate::api;
/// An error that can occur during client operations.
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
pub enum Error<E> {
/// Queried endpoint requires authentication but was called on an anonymous client.
AuthenticationRequired,
/// 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).
Response(ResponseError),
/// Converting the HTTP response to one of ruma's types failed.
FromHttpResponse(FromHttpResponseError<api::Error>),
FromHttpResponse(FromHttpResponseError<E>),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
impl<E> Display for Error<E> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::AuthenticationRequired => {
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 {
Error::IntoHttp(err)
}
}
#[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 {
Error::Url(UrlError(err))
}
}
#[doc(hidden)]
impl From<hyper::Error> for Error {
impl<E> From<hyper::Error> for Error<E> {
fn from(err: hyper::Error) -> Self {
Error::Response(ResponseError(err))
}
}
impl From<FromHttpResponseError<api::Error>> for Error {
fn from(err: FromHttpResponseError<api::Error>) -> Self {
impl<E> From<FromHttpResponseError<E>> for Error<E> {
fn from(err: FromHttpResponseError<E>) -> Self {
Error::FromHttpResponse(err)
}
}
impl StdError for Error {}
impl<E: Debug> std::error::Error for Error<E> {}
#[derive(Debug)]
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.
//! // 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? {
//! // Do something with the data in the response...
//! }
//! # Result::<(), ruma_client::Error>::Ok(())
//! # Result::<(), ruma_client::Error<_>>::Ok(())
//! # };
//! ```
//!
@ -91,7 +91,7 @@
//! .await?;
//!
//! 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,
device_id: Option<DeviceId>,
initial_device_display_name: Option<String>,
) -> Result<Session, Error> {
) -> Result<Session, Error<api::Error>> {
use api::r0::session::login;
let response = self
@ -251,7 +251,7 @@ where
/// Register as a guest. In contrast to `api::r0::account::register::call()`,
/// this method stores the session data returned by the endpoint in this
/// 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;
let response = self
@ -293,7 +293,7 @@ where
&self,
username: Option<String>,
password: String,
) -> Result<Session, Error> {
) -> Result<Session, Error<api::Error>> {
use api::r0::account::register;
let response = self
@ -334,8 +334,9 @@ where
since: Option<String>,
set_presence: api::r0::sync::sync_events::SetPresence,
timeout: Option<Duration>,
) -> impl Stream<Item = Result<api::r0::sync::sync_events::IncomingResponse, Error>>
+ TryStream<Ok = api::r0::sync::sync_events::IncomingResponse, Error = Error> {
) -> impl Stream<Item = Result<api::r0::sync::sync_events::IncomingResponse, Error<api::Error>>>
+ TryStream<Ok = api::r0::sync::sync_events::IncomingResponse, Error = Error<api::Error>>
{
use api::r0::sync::sync_events;
let client = self.clone();
@ -361,32 +362,32 @@ where
}
/// Makes a request to a Matrix API endpoint.
pub fn request<Request: Endpoint<ResponseError = api::Error>>(
pub fn request<Request: Endpoint>(
&self,
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.
// See https://github.com/rust-lang/rust/issues/54149
where
Request::Incoming: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>,
<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)
}
/// 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,
request: Request,
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.
// See https://github.com/rust-lang/rust/issues/54149
where
Request::Incoming: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>,
<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();