diff --git a/ruma-api-macros/src/api/request.rs b/ruma-api-macros/src/api/request.rs index 3f293b72..a2bfcb90 100644 --- a/ruma-api-macros/src/api/request.rs +++ b/ruma-api-macros/src/api/request.rs @@ -304,7 +304,7 @@ impl Request { body => body, }; - #ruma_api::try_deserialize!(request, #serde_json::from_slice(json)) + #serde_json::from_slice(json)? }; } } else { @@ -330,14 +330,11 @@ impl Request { _ => ( quote! { str_value.to_owned() }, quote! { - // FIXME: Not a missing json field, a missing header! - return Err(#ruma_api::error::RequestDeserializationError::new( + return Err( #ruma_api::error::HeaderDeserializationError::MissingHeader( #header_name_string.into() - ), - request, + ).into(), ) - .into()) }, ), }; @@ -345,8 +342,7 @@ impl Request { quote! { #field_name: match headers.get(#http::header::#header_name) { Some(header_value) => { - let str_value = - #ruma_api::try_deserialize!(request, header_value.to_str()); + let str_value = header_value.to_str()?; #some_case } None => #none_case, @@ -604,22 +600,16 @@ impl Request { if self.query_map_field().is_some() { quote! { - let request_query = #ruma_api::try_deserialize!( - request, - #ruma_serde::urlencoded::from_str( - &request.uri().query().unwrap_or("") - ), - ); + let request_query = #ruma_serde::urlencoded::from_str( + &request.uri().query().unwrap_or(""), + )?; } } else if self.has_query_fields() { quote! { let request_query: ::Incoming = - #ruma_api::try_deserialize!( - request, - #ruma_serde::urlencoded::from_str( - &request.uri().query().unwrap_or("") - ), - ); + #ruma_serde::urlencoded::from_str( + &request.uri().query().unwrap_or("") + )?; } } else { TokenStream::new() @@ -741,16 +731,10 @@ impl Request { quote! { #path_var_ident: { let segment = path_segments[#i].as_bytes(); - let decoded = #ruma_api::try_deserialize!( - request, - #percent_encoding::percent_decode(segment) - .decode_utf8(), - ); + let decoded = + #percent_encoding::percent_decode(segment).decode_utf8()?; - #ruma_api::try_deserialize!( - request, - ::std::convert::TryFrom::try_from(&*decoded), - ) + ::std::convert::TryFrom::try_from(&*decoded)? } } }, diff --git a/ruma-api/src/error.rs b/ruma-api/src/error.rs index f22b219a..1ce59d31 100644 --- a/ruma-api/src/error.rs +++ b/ruma-api/src/error.rs @@ -65,7 +65,7 @@ pub enum IntoHttpError { pub enum FromHttpRequestError { /// Deserialization failed #[error("deserialization failed: {0}")] - Deserialization(#[from] RequestDeserializationError), + Deserialization(RequestDeserializationError), /// HTTP method mismatch #[error("http method mismatch: expected {expected}, received: {received}")] @@ -77,22 +77,28 @@ pub enum FromHttpRequestError { }, } +impl From for FromHttpRequestError +where + T: Into, +{ + fn from(err: T) -> Self { + Self::Deserialization(err.into()) + } +} + /// An error that occurred when trying to deserialize a request. #[derive(Debug, Error)] #[error("{inner}")] pub struct RequestDeserializationError { inner: DeserializationError, - http_request: http::Request>, } -impl RequestDeserializationError { - /// Creates a new `RequestDeserializationError` from the given deserialization error and http - /// request. - pub fn new( - inner: impl Into, - http_request: http::Request>, - ) -> Self { - Self { inner: inner.into(), http_request } +impl From for RequestDeserializationError +where + T: Into, +{ + fn from(err: T) -> Self { + Self { inner: err.into() } } } diff --git a/ruma-api/src/lib.rs b/ruma-api/src/lib.rs index 21b3688b..a696c476 100644 --- a/ruma-api/src/lib.rs +++ b/ruma-api/src/lib.rs @@ -363,17 +363,3 @@ pub struct Metadata { /// What authentication scheme the server uses for this endpoint. pub authentication: AuthScheme, } - -#[doc(hidden)] -#[macro_export] -macro_rules! try_deserialize { - ($kind:ident, $call:expr $(,)?) => { - $crate::try_deserialize!(@$kind, $kind, $call) - }; - (@request, $kind:ident, $call:expr) => { - match $call { - Ok(val) => val, - Err(err) => return Err($crate::error::RequestDeserializationError::new(err, $kind).into()), - } - }; -} diff --git a/ruma-api/tests/manual_endpoint_impl.rs b/ruma-api/tests/manual_endpoint_impl.rs index 65e2190c..fe39ddd0 100644 --- a/ruma-api/tests/manual_endpoint_impl.rs +++ b/ruma-api/tests/manual_endpoint_impl.rs @@ -6,8 +6,7 @@ use bytes::Buf; use http::{header::CONTENT_TYPE, method::Method}; use ruma_api::{ error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, ServerError, Void}, - try_deserialize, AuthScheme, EndpointError, IncomingRequest, IncomingResponse, Metadata, - OutgoingRequest, + AuthScheme, EndpointError, IncomingRequest, IncomingResponse, Metadata, OutgoingRequest, }; use ruma_identifiers::{RoomAliasId, RoomId}; use ruma_serde::Outgoing; @@ -70,19 +69,16 @@ impl IncomingRequest for Request { fn try_from_http_request( request: http::Request>, ) -> Result { - let request_body: RequestBody = - try_deserialize!(request, serde_json::from_slice(request.body().as_slice())); + let request_body: RequestBody = serde_json::from_slice(request.body().as_slice())?; let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect(); Ok(Request { room_id: request_body.room_id, room_alias: { - let decoded = try_deserialize!( - request, - percent_encoding::percent_decode(path_segments[5].as_bytes()).decode_utf8(), - ); + let decoded = + percent_encoding::percent_decode(path_segments[5].as_bytes()).decode_utf8()?; - try_deserialize!(request, TryFrom::try_from(&*decoded)) + TryFrom::try_from(&*decoded)? }, }) } diff --git a/ruma-client-api/src/r0/message/send_message_event.rs b/ruma-client-api/src/r0/message/send_message_event.rs index 31600ef7..75ad5300 100644 --- a/ruma-client-api/src/r0/message/send_message_event.rs +++ b/ruma-client-api/src/r0/message/send_message_event.rs @@ -109,37 +109,30 @@ impl ruma_api::IncomingRequest for IncomingRequest { ) -> Result { use std::convert::TryFrom; - use ruma_api::try_deserialize; - use ruma_events::EventContent; + use ruma_events::EventContent as _; use serde_json::value::RawValue as RawJsonValue; let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect(); let room_id = { - let decoded = try_deserialize!( - request, - percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8(), - ); + let decoded = + percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()?; - try_deserialize!(request, RoomId::try_from(&*decoded)) + RoomId::try_from(&*decoded)? }; - let txn_id = try_deserialize!( - request, - percent_encoding::percent_decode(path_segments[7].as_bytes()).decode_utf8(), - ) - .into_owned(); + let txn_id = percent_encoding::percent_decode(path_segments[7].as_bytes()) + .decode_utf8()? + .into_owned(); let content = { let request_body: Box = - try_deserialize!(request, serde_json::from_slice(request.body().as_slice())); + serde_json::from_slice(request.body().as_slice())?; - let event_type = try_deserialize!( - request, - percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8() - ); + let event_type = + percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()?; - try_deserialize!(request, AnyMessageEventContent::from_parts(&event_type, request_body)) + AnyMessageEventContent::from_parts(&event_type, request_body)? }; Ok(Self { room_id, txn_id, content }) diff --git a/ruma-client-api/src/r0/state/get_state_events_for_key.rs b/ruma-client-api/src/r0/state/get_state_events_for_key.rs index 7ee0994f..cf668e82 100644 --- a/ruma-client-api/src/r0/state/get_state_events_for_key.rs +++ b/ruma-client-api/src/r0/state/get_state_events_for_key.rs @@ -113,36 +113,27 @@ impl ruma_api::IncomingRequest for IncomingRequest { ) -> Result { use std::convert::TryFrom; - use ruma_api::try_deserialize; - let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect(); let room_id = { - let decoded = try_deserialize!( - request, - percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8() - ); + let decoded = + percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()?; - try_deserialize!(request, RoomId::try_from(&*decoded)) + RoomId::try_from(&*decoded)? }; let event_type = { - let decoded = try_deserialize!( - request, - percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8() - ); + let decoded = + percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()?; - try_deserialize!(request, EventType::try_from(&*decoded)) + EventType::try_from(&*decoded)? }; let state_key = match path_segments.get(7) { Some(segment) => { - let decoded = try_deserialize!( - request, - percent_encoding::percent_decode(segment.as_bytes()).decode_utf8() - ); + let decoded = percent_encoding::percent_decode(segment.as_bytes()).decode_utf8()?; - try_deserialize!(request, String::try_from(&*decoded)) + String::try_from(&*decoded)? } None => "".into(), }; diff --git a/ruma-client-api/src/r0/state/send_state_event.rs b/ruma-client-api/src/r0/state/send_state_event.rs index 8bfb8ee7..e21f89ef 100644 --- a/ruma-client-api/src/r0/state/send_state_event.rs +++ b/ruma-client-api/src/r0/state/send_state_event.rs @@ -111,42 +111,35 @@ impl ruma_api::IncomingRequest for IncomingRequest { fn try_from_http_request( request: http::Request>, ) -> Result { - use std::convert::TryFrom; + use std::{borrow::Cow, convert::TryFrom}; - use ruma_api::try_deserialize; use ruma_events::EventContent; use serde_json::value::RawValue as RawJsonValue; let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect(); let room_id = { - let decoded = try_deserialize!( - request, - percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8() - ); + let decoded = + percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()?; - try_deserialize!(request, RoomId::try_from(&*decoded)) + RoomId::try_from(&*decoded)? }; - let state_key = match path_segments.get(7) { - Some(segment) => try_deserialize!( - request, - percent_encoding::percent_decode(segment.as_bytes()).decode_utf8() - ) - .into_owned(), - None => "".into(), - }; + let state_key = path_segments + .get(7) + .map(|segment| percent_encoding::percent_decode(segment.as_bytes()).decode_utf8()) + .transpose()? + .unwrap_or(Cow::Borrowed("")) + .into_owned(); let content = { let request_body: Box = - try_deserialize!(request, serde_json::from_slice(request.body().as_slice())); + serde_json::from_slice(request.body().as_slice())?; - let event_type = try_deserialize!( - request, - percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8() - ); + let event_type = + percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()?; - try_deserialize!(request, AnyStateEventContent::from_parts(&event_type, request_body)) + AnyStateEventContent::from_parts(&event_type, request_body)? }; Ok(Self { room_id, state_key, content })