diff --git a/ruma-api-macros/src/api.rs b/ruma-api-macros/src/api.rs index fd43cb6f..0390fb88 100644 --- a/ruma-api-macros/src/api.rs +++ b/ruma-api-macros/src/api.rs @@ -160,16 +160,10 @@ impl ToTokens for Api { let extract_request_body = if self.request.has_body_fields() || self.request.newtype_body_field().is_some() { quote! { - let request_body: RequestBody = - match ruma_api::exports::serde_json::from_slice(request.body().as_slice()) { - Ok(body) => body, - Err(err) => { - return Err( - ruma_api::error::RequestDeserializationError::new(err, request) - .into() - ); - } - }; + let request_body: RequestBody = ::ruma_api::try_deserialize!( + request, + ::ruma_api::exports::serde_json::from_slice(request.body().as_slice()) + ); } } else { TokenStream::new() @@ -193,24 +187,17 @@ impl ToTokens for Api { TokenStream::new() }; - let typed_response_body_decl = if self.response.has_body_fields() - || self.response.newtype_body_field().is_some() - { - quote! { - let response_body: ResponseBody = - match ruma_api::exports::serde_json::from_slice(response.body().as_slice()) { - Ok(body) => body, - Err(err) => { - return Err( - ruma_api::error::ResponseDeserializationError::new(err, response) - .into() - ); - } - }; - } - } else { - TokenStream::new() - }; + let typed_response_body_decl = + if self.response.has_body_fields() || self.response.newtype_body_field().is_some() { + quote! { + let response_body: ResponseBody = ::ruma_api::try_deserialize!( + response, + ::ruma_api::exports::serde_json::from_slice(response.body().as_slice()), + ); + } + } else { + TokenStream::new() + }; let response_init_fields = self.response.init_fields(); diff --git a/ruma-api-macros/src/util.rs b/ruma-api-macros/src/util.rs index dd067cb3..ba13cd47 100644 --- a/ruma-api-macros/src/util.rs +++ b/ruma-api-macros/src/util.rs @@ -62,31 +62,19 @@ pub(crate) fn request_path_string_and_parse( |(i, segment)| { let path_var = &segment[1..]; let path_var_ident = Ident::new(path_var, Span::call_site()); - quote! { #path_var_ident: { use std::ops::Deref as _; use ruma_api::error::RequestDeserializationError; let segment = path_segments.get(#i).unwrap().as_bytes(); - let decoded = match ruma_api::exports::percent_encoding::percent_decode( - segment - ).decode_utf8() { - Ok(x) => x, - Err(err) => { - return Err( - RequestDeserializationError::new(err, request).into() - ); - } - }; - match std::convert::TryFrom::try_from(decoded.deref()) { - Ok(val) => val, - Err(err) => { - return Err( - RequestDeserializationError::new(err, request).into() - ); - } - } + let decoded = ::ruma_api::try_deserialize!( + request, + ruma_api::exports::percent_encoding::percent_decode(segment) + .decode_utf8(), + ); + + ::ruma_api::try_deserialize!(request, std::convert::TryFrom::try_from(decoded.deref())) } } }, @@ -146,31 +134,21 @@ pub(crate) fn build_query_string(request: &Request) -> TokenStream { pub(crate) fn extract_request_query(request: &Request) -> TokenStream { if request.query_map_field().is_some() { quote! { - let request_query = match ruma_api::exports::ruma_serde::urlencoded::from_str( - &request.uri().query().unwrap_or("") - ) { - Ok(query) => query, - Err(err) => { - return Err( - ruma_api::error::RequestDeserializationError::new(err, request).into() - ); - } - }; + let request_query = ::ruma_api::try_deserialize!( + request, + ::ruma_api::exports::ruma_serde::urlencoded::from_str( + &request.uri().query().unwrap_or("") + ), + ); } } else if request.has_query_fields() { quote! { - let request_query: RequestQuery = - match ruma_api::exports::ruma_serde::urlencoded::from_str( + let request_query: RequestQuery = ::ruma_api::try_deserialize!( + request, + ::ruma_api::exports::ruma_serde::urlencoded::from_str( &request.uri().query().unwrap_or("") - ) { - Ok(query) => query, - Err(err) => { - return Err( - ruma_api::error::RequestDeserializationError::new(err, request) - .into() - ); - } - }; + ), + ); } } else { TokenStream::new() diff --git a/ruma-api/src/lib.rs b/ruma-api/src/lib.rs index f1d7d496..13880a15 100644 --- a/ruma-api/src/lib.rs +++ b/ruma-api/src/lib.rs @@ -267,6 +267,26 @@ pub struct Metadata { pub requires_authentication: bool, } +#[doc(hidden)] +#[macro_export] +macro_rules! try_deserialize { + ($kind:ident, $call:expr $(,)?) => { + ::ruma_api::try_deserialize!(@$kind, $kind, $call) + }; + (@request, $kind:ident, $call:expr) => { + match $call { + Ok(val) => val, + Err(err) => return Err(::ruma_api::error::RequestDeserializationError::new(err, $kind).into()), + } + }; + (@response, $kind:ident, $call:expr) => { + match $call { + Ok(val) => val, + Err(err) => return Err(::ruma_api::error::ResponseDeserializationError::new(err, $kind).into()), + } + }; +} + #[cfg(test)] mod tests { /// PUT /_matrix/client/r0/directory/room/:room_alias