Split Endpoint trait into OutgoingRequest, IncomingRequest
This commit is contained in:
parent
abc34eeb7e
commit
987d48666c
@ -101,7 +101,7 @@ impl ToTokens for Api {
|
|||||||
let request_type = &self.request;
|
let request_type = &self.request;
|
||||||
let response_type = &self.response;
|
let response_type = &self.response;
|
||||||
|
|
||||||
let request_try_from_type = if self.request.contains_lifetimes() {
|
let incoming_request_type = if self.request.contains_lifetimes() {
|
||||||
quote!(IncomingRequest)
|
quote!(IncomingRequest)
|
||||||
} else {
|
} else {
|
||||||
quote!(Request)
|
quote!(Request)
|
||||||
@ -227,22 +227,25 @@ impl ToTokens for Api {
|
|||||||
|
|
||||||
let request_lifetimes = self.request.combine_lifetimes();
|
let request_lifetimes = self.request.combine_lifetimes();
|
||||||
|
|
||||||
let non_auth_endpoint_impl = if requires_authentication.value {
|
let non_auth_endpoint_impls = if requires_authentication.value {
|
||||||
TokenStream::new()
|
TokenStream::new()
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
impl #request_lifetimes #ruma_api_import::NonAuthEndpoint
|
impl #request_lifetimes #ruma_api_import::OutgoingNonAuthRequest
|
||||||
for Request #request_lifetimes
|
for Request #request_lifetimes
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
impl #ruma_api_import::IncomingNonAuthRequest for #incoming_request_type {}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let api = quote! {
|
let api = quote! {
|
||||||
|
|
||||||
#[doc = #request_doc]
|
#[doc = #request_doc]
|
||||||
#request_type
|
#request_type
|
||||||
|
|
||||||
impl ::std::convert::TryFrom<#ruma_api_import::exports::http::Request<Vec<u8>>> for #request_try_from_type {
|
impl ::std::convert::TryFrom<#ruma_api_import::exports::http::Request<Vec<u8>>>
|
||||||
|
for #incoming_request_type
|
||||||
|
{
|
||||||
type Error = #ruma_api_import::error::FromHttpRequestError;
|
type Error = #ruma_api_import::error::FromHttpRequestError;
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
@ -308,14 +311,7 @@ impl ToTokens for Api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #request_lifetimes #ruma_api_import::Endpoint for Request #request_lifetimes {
|
const __METADATA: #ruma_api_import::Metadata = #ruma_api_import::Metadata {
|
||||||
type Response = Response;
|
|
||||||
type ResponseError = #error;
|
|
||||||
type IncomingRequest = <Self as #ruma_api_import::Outgoing>::Incoming;
|
|
||||||
type IncomingResponse = <Response as #ruma_api_import::Outgoing>::Incoming;
|
|
||||||
|
|
||||||
/// Metadata for the `#name` endpoint.
|
|
||||||
const METADATA: #ruma_api_import::Metadata = #ruma_api_import::Metadata {
|
|
||||||
description: #description,
|
description: #description,
|
||||||
method: #ruma_api_import::exports::http::Method::#method,
|
method: #ruma_api_import::exports::http::Method::#method,
|
||||||
name: #name,
|
name: #name,
|
||||||
@ -324,6 +320,16 @@ impl ToTokens for Api {
|
|||||||
requires_authentication: #requires_authentication,
|
requires_authentication: #requires_authentication,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
impl #request_lifetimes #ruma_api_import::OutgoingRequest
|
||||||
|
for Request #request_lifetimes
|
||||||
|
{
|
||||||
|
type EndpointError = #error;
|
||||||
|
type IncomingResponse = <Response as #ruma_api_import::Outgoing>::Incoming;
|
||||||
|
|
||||||
|
// FIXME: Doc string interpolation
|
||||||
|
/// Metadata for the `#name` endpoint.
|
||||||
|
const METADATA: #ruma_api_import::Metadata = __METADATA;
|
||||||
|
|
||||||
#[allow(unused_mut, unused_variables)]
|
#[allow(unused_mut, unused_variables)]
|
||||||
fn try_into_http_request(
|
fn try_into_http_request(
|
||||||
self,
|
self,
|
||||||
@ -333,7 +339,7 @@ impl ToTokens for Api {
|
|||||||
#ruma_api_import::exports::http::Request<Vec<u8>>,
|
#ruma_api_import::exports::http::Request<Vec<u8>>,
|
||||||
#ruma_api_import::error::IntoHttpError,
|
#ruma_api_import::error::IntoHttpError,
|
||||||
> {
|
> {
|
||||||
let metadata = Request::METADATA;
|
let metadata = <Self as #ruma_api_import::OutgoingRequest>::METADATA;
|
||||||
|
|
||||||
let http_request = #ruma_api_import::exports::http::Request::builder()
|
let http_request = #ruma_api_import::exports::http::Request::builder()
|
||||||
.method(#ruma_api_import::exports::http::Method::#method)
|
.method(#ruma_api_import::exports::http::Method::#method)
|
||||||
@ -350,7 +356,16 @@ impl ToTokens for Api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#non_auth_endpoint_impl
|
impl #ruma_api_import::IncomingRequest for #incoming_request_type {
|
||||||
|
type EndpointError = #error;
|
||||||
|
type OutgoingResponse = Response;
|
||||||
|
|
||||||
|
// FIXME: Doc string interpolation
|
||||||
|
/// Metadata for the `#name` endpoint.
|
||||||
|
const METADATA: #ruma_api_import::Metadata = __METADATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
#non_auth_endpoint_impls
|
||||||
};
|
};
|
||||||
|
|
||||||
api.to_tokens(tokens);
|
api.to_tokens(tokens);
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
|
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
|
use crate::EndpointError;
|
||||||
|
|
||||||
// FIXME when `!` becomes stable use it
|
// FIXME when `!` becomes stable use it
|
||||||
/// Default `ResponseError` for `ruma_api!` macro
|
/// Default `EndpointError` for `ruma_api!` macro
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Void {}
|
pub enum Void {}
|
||||||
|
|
||||||
impl crate::EndpointError for Void {
|
impl EndpointError for Void {
|
||||||
fn try_from_response(
|
fn try_from_response(
|
||||||
response: http::Response<Vec<u8>>,
|
response: http::Response<Vec<u8>>,
|
||||||
) -> Result<Self, ResponseDeserializationError> {
|
) -> Result<Self, ResponseDeserializationError> {
|
||||||
|
@ -242,22 +242,15 @@ pub trait EndpointError: std::error::Error + Sized {
|
|||||||
) -> Result<Self, error::ResponseDeserializationError>;
|
) -> Result<Self, error::ResponseDeserializationError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Matrix API endpoint.
|
/// A request type for a Matrix API endpoint. (trait used for sending requests)
|
||||||
///
|
pub trait OutgoingRequest {
|
||||||
/// The type implementing this trait contains any data needed to make a request to the endpoint.
|
/// A type capturing the expected error conditions the server can return.
|
||||||
pub trait Endpoint: Outgoing<Incoming = <Self as Endpoint>::IncomingRequest> {
|
type EndpointError: EndpointError;
|
||||||
/// Data returned in a successful response from the endpoint.
|
|
||||||
type Response: Outgoing<Incoming = Self::IncomingResponse>
|
|
||||||
+ TryInto<http::Response<Vec<u8>>, Error = IntoHttpError>;
|
|
||||||
/// Error type returned when response from endpoint fails.
|
|
||||||
type ResponseError: EndpointError;
|
|
||||||
|
|
||||||
/// Shorthand for `<Self as Outgoing>::Incoming`.
|
/// Response type returned when the request is successful.
|
||||||
type IncomingRequest: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>;
|
|
||||||
/// Shorthand for `<Self::Response as Outgoing>::Incoming`.
|
|
||||||
type IncomingResponse: TryFrom<
|
type IncomingResponse: TryFrom<
|
||||||
http::Response<Vec<u8>>,
|
http::Response<Vec<u8>>,
|
||||||
Error = FromHttpResponseError<<Self as Endpoint>::ResponseError>,
|
Error = FromHttpResponseError<Self::EndpointError>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// Metadata about the endpoint.
|
/// Metadata about the endpoint.
|
||||||
@ -278,11 +271,23 @@ pub trait Endpoint: Outgoing<Incoming = <Self as Endpoint>::IncomingRequest> {
|
|||||||
) -> Result<http::Request<Vec<u8>>, IntoHttpError>;
|
) -> Result<http::Request<Vec<u8>>, IntoHttpError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Matrix API endpoint that doesn't require authentication.
|
/// A request type for a Matrix API endpoint. (trait used for receiving requests)
|
||||||
///
|
pub trait IncomingRequest: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError> {
|
||||||
/// This marker trait is to indicate that a type implementing `Endpoint` doesn't require any
|
/// A type capturing the error conditions that can be returned in the response.
|
||||||
/// authentication.
|
type EndpointError: EndpointError;
|
||||||
pub trait NonAuthEndpoint: Endpoint {}
|
|
||||||
|
/// Response type to return when the request is successful.
|
||||||
|
type OutgoingResponse: TryInto<http::Response<Vec<u8>>, Error = IntoHttpError>;
|
||||||
|
|
||||||
|
/// Metadata about the endpoint.
|
||||||
|
const METADATA: Metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Marker trait for requests that don't require authentication. (for the client side)
|
||||||
|
pub trait OutgoingNonAuthRequest: OutgoingRequest {}
|
||||||
|
|
||||||
|
/// Marker trait for requests that don't require authentication. (for the server side)
|
||||||
|
pub trait IncomingNonAuthRequest: IncomingRequest {}
|
||||||
|
|
||||||
/// Metadata about an API endpoint.
|
/// Metadata about an API endpoint.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use ruma_api::{ruma_api, Endpoint as _};
|
use ruma_api::{ruma_api, OutgoingRequest as _};
|
||||||
use ruma_identifiers::{user_id, UserId};
|
use ruma_identifiers::{user_id, UserId};
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
|
@ -10,7 +10,7 @@ use ruma_api::{
|
|||||||
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
FromHttpRequestError, FromHttpResponseError, IntoHttpError, RequestDeserializationError,
|
||||||
ResponseDeserializationError, ServerError, Void,
|
ResponseDeserializationError, ServerError, Void,
|
||||||
},
|
},
|
||||||
Endpoint, Metadata, Outgoing,
|
IncomingRequest, Metadata, Outgoing, OutgoingRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A request to create a new room alias.
|
/// A request to create a new room alias.
|
||||||
@ -24,12 +24,6 @@ impl Outgoing for Request {
|
|||||||
type Incoming = Self;
|
type Incoming = Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Endpoint for Request {
|
|
||||||
type Response = Response;
|
|
||||||
type ResponseError = Void;
|
|
||||||
type IncomingRequest = Self;
|
|
||||||
type IncomingResponse = Response;
|
|
||||||
|
|
||||||
const METADATA: Metadata = Metadata {
|
const METADATA: Metadata = Metadata {
|
||||||
description: "Add an alias to a room.",
|
description: "Add an alias to a room.",
|
||||||
method: Method::PUT,
|
method: Method::PUT,
|
||||||
@ -39,20 +33,24 @@ impl Endpoint for Request {
|
|||||||
requires_authentication: false,
|
requires_authentication: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
impl OutgoingRequest for Request {
|
||||||
|
type EndpointError = Void;
|
||||||
|
type IncomingResponse = Response;
|
||||||
|
|
||||||
|
const METADATA: Metadata = METADATA;
|
||||||
|
|
||||||
fn try_into_http_request(
|
fn try_into_http_request(
|
||||||
self,
|
self,
|
||||||
base_url: &str,
|
base_url: &str,
|
||||||
_access_token: Option<&str>,
|
_access_token: Option<&str>,
|
||||||
) -> Result<http::Request<Vec<u8>>, IntoHttpError> {
|
) -> Result<http::Request<Vec<u8>>, IntoHttpError> {
|
||||||
let metadata = Request::METADATA;
|
let url = (base_url.to_owned() + METADATA.path)
|
||||||
|
|
||||||
let url = (base_url.to_owned() + metadata.path)
|
|
||||||
.replace(":room_alias", &self.room_alias.to_string());
|
.replace(":room_alias", &self.room_alias.to_string());
|
||||||
|
|
||||||
let request_body = RequestBody { room_id: self.room_id };
|
let request_body = RequestBody { room_id: self.room_id };
|
||||||
|
|
||||||
let http_request = http::Request::builder()
|
let http_request = http::Request::builder()
|
||||||
.method(metadata.method)
|
.method(METADATA.method)
|
||||||
.uri(url)
|
.uri(url)
|
||||||
.body(serde_json::to_vec(&request_body)?)
|
.body(serde_json::to_vec(&request_body)?)
|
||||||
// this cannot fail because we don't give user-supplied data to any of the
|
// this cannot fail because we don't give user-supplied data to any of the
|
||||||
@ -63,6 +61,13 @@ impl Endpoint for Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IncomingRequest for Request {
|
||||||
|
type EndpointError = Void;
|
||||||
|
type OutgoingResponse = Response;
|
||||||
|
|
||||||
|
const METADATA: Metadata = METADATA;
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<http::Request<Vec<u8>>> for Request {
|
impl TryFrom<http::Request<Vec<u8>>> for Request {
|
||||||
type Error = FromHttpRequestError;
|
type Error = FromHttpRequestError;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use ruma_api::{ruma_api, Endpoint};
|
use ruma_api::{ruma_api, OutgoingRequest as _};
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata: {
|
metadata: {
|
||||||
|
@ -56,7 +56,7 @@ mod tests {
|
|||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
use js_int::uint;
|
use js_int::uint;
|
||||||
use ruma_api::Endpoint as _;
|
use ruma_api::OutgoingRequest as _;
|
||||||
|
|
||||||
use super::{Request, Response};
|
use super::{Request, Response};
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ mod tests {
|
|||||||
use super::{Direction, Request};
|
use super::{Direction, Request};
|
||||||
|
|
||||||
use js_int::uint;
|
use js_int::uint;
|
||||||
use ruma_api::Endpoint;
|
use ruma_api::OutgoingRequest;
|
||||||
use ruma_identifiers::room_id;
|
use ruma_identifiers::room_id;
|
||||||
|
|
||||||
use crate::r0::filter::{LazyLoadOptions, RoomEventFilter};
|
use crate::r0::filter::{LazyLoadOptions, RoomEventFilter};
|
||||||
|
@ -140,7 +140,7 @@ mod user_serde;
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ruma_api::Endpoint;
|
use ruma_api::OutgoingRequest;
|
||||||
use serde_json::{from_value as from_json_value, json, Value as JsonValue};
|
use serde_json::{from_value as from_json_value, json, Value as JsonValue};
|
||||||
|
|
||||||
use super::{LoginInfo, Medium, Request, UserInfo};
|
use super::{LoginInfo, Medium, Request, UserInfo};
|
||||||
|
@ -403,7 +403,7 @@ impl DeviceLists {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::{convert::TryInto, time::Duration};
|
use std::{convert::TryInto, time::Duration};
|
||||||
|
|
||||||
use ruma_api::Endpoint;
|
use ruma_api::OutgoingRequest;
|
||||||
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
||||||
|
|
||||||
use matches::assert_matches;
|
use matches::assert_matches;
|
||||||
|
@ -113,7 +113,7 @@ use http::{uri::Uri, Response as HttpResponse};
|
|||||||
use hyper::{client::HttpConnector, Client as HyperClient};
|
use hyper::{client::HttpConnector, Client as HyperClient};
|
||||||
#[cfg(feature = "hyper-tls")]
|
#[cfg(feature = "hyper-tls")]
|
||||||
use hyper_tls::HttpsConnector;
|
use hyper_tls::HttpsConnector;
|
||||||
use ruma_api::Endpoint;
|
use ruma_api::OutgoingRequest;
|
||||||
use ruma_client_api::r0::sync::sync_events::{
|
use ruma_client_api::r0::sync::sync_events::{
|
||||||
Filter as SyncFilter, Request as SyncRequest, Response as SyncResponse,
|
Filter as SyncFilter, Request as SyncRequest, Response as SyncResponse,
|
||||||
};
|
};
|
||||||
@ -350,19 +350,19 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a request to a Matrix API endpoint.
|
/// Makes a request to a Matrix API endpoint.
|
||||||
pub async fn request<Request: Endpoint>(
|
pub async fn request<Request: OutgoingRequest>(
|
||||||
&self,
|
&self,
|
||||||
request: Request,
|
request: Request,
|
||||||
) -> Result<Request::IncomingResponse, Error<Request::ResponseError>> {
|
) -> Result<Request::IncomingResponse, Error<Request::EndpointError>> {
|
||||||
self.request_with_url_params(request, None).await
|
self.request_with_url_params(request, None).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 async fn request_with_url_params<Request: Endpoint>(
|
pub async fn request_with_url_params<Request: OutgoingRequest>(
|
||||||
&self,
|
&self,
|
||||||
request: Request,
|
request: Request,
|
||||||
extra_params: Option<BTreeMap<String, String>>,
|
extra_params: Option<BTreeMap<String, String>>,
|
||||||
) -> Result<Request::IncomingResponse, Error<Request::ResponseError>> {
|
) -> Result<Request::IncomingResponse, Error<Request::EndpointError>> {
|
||||||
let client = self.0.clone();
|
let client = self.0.clone();
|
||||||
let mut http_request = {
|
let mut http_request = {
|
||||||
let session;
|
let session;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user