diff --git a/ruma-api-macros/src/api.rs b/ruma-api-macros/src/api.rs index 56c98d78..6feb7e1f 100644 --- a/ruma-api-macros/src/api.rs +++ b/ruma-api-macros/src/api.rs @@ -1,7 +1,7 @@ //! Details of the `ruma_api` procedural macro. use proc_macro2::TokenStream; -use quote::{quote, ToTokens}; +use quote::quote; use syn::{ parse::{Parse, ParseStream}, Token, Type, @@ -27,19 +27,27 @@ pub struct Api { response: Response, /// The `error` section of the macro. - error_ty: TokenStream, + error_ty: Option, +} + +mod kw { + syn::custom_keyword!(error); } impl Parse for Api { fn parse(input: ParseStream<'_>) -> syn::Result { - let ruma_api = util::import_ruma_api(); - let metadata: Metadata = input.parse()?; let request: Request = input.parse()?; let response: Response = input.parse()?; - let error_ty = match input.parse::() { - Ok(err) => err.ty.to_token_stream(), - Err(_) => quote! { #ruma_api::error::Void }, + + // TODO: Use `bool::then` when MSRV >= 1.50 + let error_ty = if input.peek(kw::error) { + let _: kw::error = input.parse()?; + let _: Token![:] = input.parse()?; + + Some(input.parse()?) + } else { + None }; let newtype_body_field = request.newtype_body_field(); @@ -252,7 +260,9 @@ pub fn expand_all(api: Api) -> syn::Result { format!("Data for a request to the `{}` API endpoint.\n\n{}", name, description.value()); let response_doc = format!("Data in the response from the `{}` API endpoint.", name); - let error = &api.error_ty; + let error_ty = + api.error_ty.map_or_else(|| quote! { #ruma_api::error::Void }, |err_ty| quote! { #err_ty }); + let request_lifetimes = api.request.combine_lifetimes(); let non_auth_endpoint_impls: TokenStream = api @@ -313,7 +323,7 @@ pub fn expand_all(api: Api) -> syn::Result { #[automatically_derived] #[cfg(feature = "client")] impl ::std::convert::TryFrom<#http::Response>> for Response { - type Error = #ruma_api::error::FromHttpResponseError<#error>; + type Error = #ruma_api::error::FromHttpResponseError<#error_ty>; fn try_from( response: #http::Response>, @@ -327,7 +337,7 @@ pub fn expand_all(api: Api) -> syn::Result { #response_init_fields }) } else { - match <#error as #ruma_api::EndpointError>::try_from_response(response) { + match <#error_ty as #ruma_api::EndpointError>::try_from_response(response) { Ok(err) => Err(#ruma_api::error::ServerError::Known(err).into()), Err(response_err) => { Err(#ruma_api::error::ServerError::Unknown(response_err).into()) @@ -350,7 +360,7 @@ pub fn expand_all(api: Api) -> syn::Result { #[automatically_derived] #[cfg(feature = "client")] impl #request_lifetimes #ruma_api::OutgoingRequest for Request #request_lifetimes { - type EndpointError = #error; + type EndpointError = #error_ty; type IncomingResponse = ::Incoming; #[doc = #metadata_doc] @@ -388,7 +398,7 @@ pub fn expand_all(api: Api) -> syn::Result { #[automatically_derived] #[cfg(feature = "server")] impl #ruma_api::IncomingRequest for #incoming_request_type { - type EndpointError = #error; + type EndpointError = #error_ty; type OutgoingResponse = Response; #[doc = #metadata_doc] @@ -414,22 +424,3 @@ pub fn expand_all(api: Api) -> syn::Result { #non_auth_endpoint_impls }) } - -mod kw { - syn::custom_keyword!(error); -} - -pub struct ErrorType { - pub error_kw: kw::error, - pub ty: Type, -} - -impl Parse for ErrorType { - fn parse(input: ParseStream<'_>) -> syn::Result { - let error_kw = input.parse::()?; - input.parse::()?; - let ty = input.parse()?; - - Ok(Self { error_kw, ty }) - } -}