diff --git a/ruma-api-macros/src/api.rs b/ruma-api-macros/src/api.rs index 98aae9e2..d71039a2 100644 --- a/ruma-api-macros/src/api.rs +++ b/ruma-api-macros/src/api.rs @@ -49,7 +49,7 @@ impl TryFrom for Api { let res = Self { metadata: raw_api.metadata, - request: raw_api.request.try_into()?, + request: raw_api.request, response: raw_api.response.try_into()?, error: match raw_api.error { Some(raw_err) => raw_err.ty.to_token_stream(), @@ -399,7 +399,6 @@ impl ToTokens for Api { mod kw { use syn::custom_keyword; - custom_keyword!(request); custom_keyword!(response); custom_keyword!(error); } @@ -410,7 +409,7 @@ pub struct RawApi { pub metadata: Metadata, /// The `request` section of the macro. - pub request: RawRequest, + pub request: Request, /// The `response` section of the macro. pub response: RawResponse, @@ -430,31 +429,6 @@ impl Parse for RawApi { } } -pub struct RawRequest { - pub attributes: Vec, - pub request_kw: kw::request, - pub fields: Vec, -} - -impl Parse for RawRequest { - fn parse(input: ParseStream<'_>) -> syn::Result { - let attributes = input.call(Attribute::parse_outer)?; - let request_kw = input.parse::()?; - input.parse::()?; - let fields; - braced!(fields in input); - - Ok(Self { - attributes, - request_kw, - fields: fields - .parse_terminated::(Field::parse_named)? - .into_iter() - .collect(), - }) - } -} - pub struct RawResponse { pub attributes: Vec, pub response_kw: kw::response, diff --git a/ruma-api-macros/src/api/request.rs b/ruma-api-macros/src/api/request.rs index a7c5f031..c9263fc1 100644 --- a/ruma-api-macros/src/api/request.rs +++ b/ruma-api-macros/src/api/request.rs @@ -1,19 +1,28 @@ //! Details of the `request` section of the procedural macro. -use std::{collections::BTreeSet, convert::TryFrom, mem}; +use std::{collections::BTreeSet, mem}; use proc_macro2::TokenStream; use quote::{quote, quote_spanned, ToTokens}; -use syn::{spanned::Spanned, Attribute, Field, Ident, Lifetime}; +use syn::{ + braced, + parse::{Parse, ParseStream}, + spanned::Spanned, + Attribute, Field, Ident, Lifetime, Token, +}; use crate::{ api::{ attribute::{Meta, MetaNameValue}, - strip_serde_attrs, RawRequest, + strip_serde_attrs, }, util, }; +mod kw { + syn::custom_keyword!(request); +} + #[derive(Debug, Default)] pub struct RequestLifetimes { body: BTreeSet, @@ -286,16 +295,21 @@ impl Request { } } -impl TryFrom for Request { - type Error = syn::Error; +impl Parse for Request { + fn parse(input: ParseStream<'_>) -> syn::Result { + let attributes = input.call(Attribute::parse_outer)?; + let request_kw = input.parse::()?; + input.parse::()?; + let fields; + braced!(fields in input); + + let fields = fields.parse_terminated::(Field::parse_named)?; - fn try_from(raw: RawRequest) -> syn::Result { let mut newtype_body_field = None; let mut query_map_field = None; let mut lifetimes = RequestLifetimes::default(); - let fields = raw - .fields + let fields = fields .into_iter() .map(|mut field| { let mut field_kind = None; @@ -392,7 +406,7 @@ impl TryFrom for Request { if newtype_body_field.is_some() && fields.iter().any(|f| f.is_body()) { // TODO: highlight conflicting fields, return Err(syn::Error::new_spanned( - raw.request_kw, + request_kw, "Can't have both a newtype body field and regular body fields", )); } @@ -400,7 +414,7 @@ impl TryFrom for Request { if query_map_field.is_some() && fields.iter().any(|f| f.is_query()) { return Err(syn::Error::new_spanned( // TODO: raw, - raw.request_kw, + request_kw, "Can't have both a query map field and regular query fields", )); } @@ -408,17 +422,12 @@ impl TryFrom for Request { // TODO when/if `&[(&str, &str)]` is supported remove this if query_map_field.is_some() && !lifetimes.query.is_empty() { return Err(syn::Error::new_spanned( - raw.request_kw, + request_kw, "Lifetimes are not allowed for query_map fields", )); } - Ok(Self { - attributes: raw.attributes, - fields, - lifetimes, - ruma_api_import: util::import_ruma_api(), - }) + Ok(Self { attributes, fields, lifetimes, ruma_api_import: util::import_ruma_api() }) } }