api: Introduce OutgoingResponse trait
This commit is contained in:
parent
6f5c1ee953
commit
b122dcc135
@ -116,7 +116,7 @@ impl Response {
|
||||
if segments.last().unwrap().ident == "Option" =>
|
||||
{
|
||||
quote! {
|
||||
if let Some(header) = response.#field_name {
|
||||
if let Some(header) = self.#field_name {
|
||||
headers
|
||||
.insert(
|
||||
#http::header::#header_name,
|
||||
@ -129,7 +129,7 @@ impl Response {
|
||||
headers
|
||||
.insert(
|
||||
#http::header::#header_name,
|
||||
response.#field_name.parse()?,
|
||||
self.#field_name.parse()?,
|
||||
);
|
||||
},
|
||||
};
|
||||
@ -152,13 +152,13 @@ impl Response {
|
||||
if let Some(field) = self.newtype_raw_body_field() {
|
||||
let field_name = field.ident.as_ref().expect("expected field to have an identifier");
|
||||
let span = field.span();
|
||||
return quote_spanned!(span=> response.#field_name);
|
||||
return quote_spanned!(span=> self.#field_name);
|
||||
}
|
||||
|
||||
let body = if let Some(field) = self.newtype_body_field() {
|
||||
let field_name = field.ident.as_ref().expect("expected field to have an identifier");
|
||||
let span = field.span();
|
||||
quote_spanned!(span=> response.#field_name)
|
||||
quote_spanned!(span=> self.#field_name)
|
||||
} else {
|
||||
let fields = self.fields.iter().filter_map(|response_field| {
|
||||
if let ResponseField::Body(ref field) = *response_field {
|
||||
@ -170,7 +170,7 @@ impl Response {
|
||||
|
||||
Some(quote_spanned! {span=>
|
||||
#( #cfg_attrs )*
|
||||
#field_name: response.#field_name
|
||||
#field_name: self.#field_name
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@ -285,10 +285,13 @@ impl Response {
|
||||
|
||||
#[automatically_derived]
|
||||
#[cfg(feature = "server")]
|
||||
impl ::std::convert::TryFrom<Response> for #http::Response<Vec<u8>> {
|
||||
type Error = #ruma_api::error::IntoHttpError;
|
||||
|
||||
fn try_from(response: Response) -> ::std::result::Result<Self, Self::Error> {
|
||||
impl #ruma_api::OutgoingResponse for Response {
|
||||
fn try_into_http_response(
|
||||
self,
|
||||
) -> ::std::result::Result<
|
||||
#http::Response<::std::vec::Vec<u8>>,
|
||||
#ruma_api::error::IntoHttpError,
|
||||
> {
|
||||
let mut resp_builder = #http::Response::builder()
|
||||
.header(#http::header::CONTENT_TYPE, "application/json");
|
||||
|
||||
@ -300,8 +303,7 @@ impl Response {
|
||||
// This cannot fail because we parse each header value
|
||||
// checking for errors as each value is inserted and
|
||||
// we only allow keys from the `http::header` module.
|
||||
let response = resp_builder.body(#body).unwrap();
|
||||
Ok(response)
|
||||
Ok(resp_builder.body(#body).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#[cfg(not(all(feature = "client", feature = "server")))]
|
||||
compile_error!("ruma_api's Cargo features only exist as a workaround are not meant to be disabled");
|
||||
|
||||
use std::{convert::TryInto, error::Error as StdError};
|
||||
use std::{convert::TryInto as _, error::Error as StdError};
|
||||
|
||||
use bytes::Buf;
|
||||
use http::Method;
|
||||
@ -306,7 +306,7 @@ pub trait IncomingRequest: Sized {
|
||||
type EndpointError: EndpointError;
|
||||
|
||||
/// Response type to return when the request is successful.
|
||||
type OutgoingResponse: TryInto<http::Response<Vec<u8>>, Error = IntoHttpError>;
|
||||
type OutgoingResponse: OutgoingResponse;
|
||||
|
||||
/// Metadata about the endpoint.
|
||||
const METADATA: Metadata;
|
||||
@ -315,6 +315,15 @@ pub trait IncomingRequest: Sized {
|
||||
fn try_from_http_request(req: http::Request<Vec<u8>>) -> Result<Self, FromHttpRequestError>;
|
||||
}
|
||||
|
||||
/// A request type for a Matrix API endpoint, used for sending responses.
|
||||
pub trait OutgoingResponse {
|
||||
/// Tries to convert this response into an `http::Response`.
|
||||
///
|
||||
/// This method should only fail when when invalid header values are specified. It may also
|
||||
/// fail with a serialization error in case of bugs in Ruma though.
|
||||
fn try_into_http_response(self) -> Result<http::Response<Vec<u8>>, IntoHttpError>;
|
||||
}
|
||||
|
||||
/// Marker trait for requests that don't require authentication, for the client side.
|
||||
pub trait OutgoingNonAuthRequest: OutgoingRequest {}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use http::header::{Entry, CONTENT_TYPE};
|
||||
use ruma_api::{ruma_api, OutgoingRequest as _};
|
||||
use ruma_api::{ruma_api, OutgoingRequest as _, OutgoingResponse as _};
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
@ -30,7 +28,7 @@ ruma_api! {
|
||||
#[test]
|
||||
fn response_content_type_override() {
|
||||
let res = Response { stuff: "magic".into() };
|
||||
let mut http_res = http::Response::<Vec<u8>>::try_from(res).unwrap();
|
||||
let mut http_res = res.try_into_http_response().unwrap();
|
||||
|
||||
// Test that we correctly replaced the default content type,
|
||||
// not adding another content-type header.
|
||||
|
@ -7,6 +7,7 @@ use http::{header::CONTENT_TYPE, method::Method};
|
||||
use ruma_api::{
|
||||
error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, ServerError, Void},
|
||||
AuthScheme, EndpointError, IncomingRequest, IncomingResponse, Metadata, OutgoingRequest,
|
||||
OutgoingResponse,
|
||||
};
|
||||
use ruma_identifiers::{RoomAliasId, RoomId};
|
||||
use ruma_serde::Outgoing;
|
||||
@ -113,10 +114,8 @@ impl IncomingResponse for Response {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Response> for http::Response<Vec<u8>> {
|
||||
type Error = IntoHttpError;
|
||||
|
||||
fn try_from(_: Response) -> Result<http::Response<Vec<u8>>, Self::Error> {
|
||||
impl OutgoingResponse for Response {
|
||||
fn try_into_http_response(self) -> Result<http::Response<Vec<u8>>, IntoHttpError> {
|
||||
let response = http::Response::builder()
|
||||
.header(CONTENT_TYPE, "application/json")
|
||||
.body(b"{}".to_vec())
|
||||
|
@ -1,6 +1,4 @@
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use ruma_api::{ruma_api, OutgoingRequest as _};
|
||||
use ruma_api::{ruma_api, OutgoingRequest as _, OutgoingResponse as _};
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
@ -27,7 +25,7 @@ fn empty_request_http_repr() {
|
||||
#[test]
|
||||
fn empty_response_http_repr() {
|
||||
let res = Response {};
|
||||
let http_res = http::Response::<Vec<u8>>::try_from(res).unwrap();
|
||||
let http_res = res.try_into_http_response().unwrap();
|
||||
|
||||
assert_eq!(http_res.body(), b"{}");
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use bytes::Buf;
|
||||
use ruma_api::{
|
||||
error::{FromHttpResponseError, IntoHttpError, Void},
|
||||
ruma_api, IncomingResponse,
|
||||
ruma_api, IncomingResponse, OutgoingResponse,
|
||||
};
|
||||
use ruma_serde::Outgoing;
|
||||
|
||||
@ -37,10 +35,8 @@ impl IncomingResponse for Response {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Response> for http::Response<Vec<u8>> {
|
||||
type Error = IntoHttpError;
|
||||
|
||||
fn try_from(_: Response) -> Result<Self, Self::Error> {
|
||||
impl OutgoingResponse for Response {
|
||||
fn try_into_http_response(self) -> Result<http::Response<Vec<u8>>, IntoHttpError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user