From 689d911cdcbb333d760d4d9c22ab68941c28f04d Mon Sep 17 00:00:00 2001 From: Jonathan de Jong Date: Wed, 9 Feb 2022 17:54:57 +0100 Subject: [PATCH] api-macros: Simplify IncomingRequest impl generation --- crates/ruma-api-macros/src/request.rs | 12 ++++++++++-- .../ruma-api-macros/src/request/incoming.rs | 19 +++---------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/crates/ruma-api-macros/src/request.rs b/crates/ruma-api-macros/src/request.rs index e47dd0fe..2c85b7f3 100644 --- a/crates/ruma-api-macros/src/request.rs +++ b/crates/ruma-api-macros/src/request.rs @@ -152,8 +152,8 @@ impl Request { self.fields.iter().filter(|f| matches!(f, RequestField::Header(..))) } - fn path_field_count(&self) -> usize { - self.fields.iter().filter(|f| matches!(f, RequestField::Path(..))).count() + fn path_fields(&self) -> impl Iterator { + self.fields.iter().filter_map(RequestField::as_path_field) } fn raw_body_field(&self) -> Option<&Field> { @@ -357,6 +357,14 @@ impl RequestField { } } + /// Return the contained field if this request field is a path kind. + pub fn as_path_field(&self) -> Option<&Field> { + match self { + RequestField::Path(field) => Some(field), + _ => None, + } + } + /// Return the contained field if this request field is a query kind. pub fn as_query_field(&self) -> Option<&Field> { match self { diff --git a/crates/ruma-api-macros/src/request/incoming.rs b/crates/ruma-api-macros/src/request/incoming.rs index b0bc76be..dc4be593 100644 --- a/crates/ruma-api-macros/src/request/incoming.rs +++ b/crates/ruma-api-macros/src/request/incoming.rs @@ -1,4 +1,4 @@ -use proc_macro2::{Ident, Span, TokenStream}; +use proc_macro2::TokenStream; use quote::quote; use syn::Field; @@ -25,20 +25,7 @@ impl Request { // except this one. If we get errors about missing fields in IncomingRequest for // a path field look here. let (parse_request_path, path_vars) = if self.has_path_fields() { - let path_string = self.path.value(); - - assert!(path_string.starts_with('/'), "path needs to start with '/'"); - assert!( - path_string.chars().filter(|c| *c == ':').count() == self.path_field_count(), - "number of declared path parameters needs to match amount of placeholders in path" - ); - - let path_vars = path_string[1..] - .split('/') - .filter(|seg| seg.starts_with(':')) - .map(|seg| Ident::new(&seg[1..], Span::call_site())); - - let vars = path_vars.clone(); + let path_vars: Vec<_> = self.path_fields().filter_map(|f| f.ident.as_ref()).collect(); let parse_request_path = quote! { let (#(#path_vars,)*) = #serde::Deserialize::deserialize( @@ -48,7 +35,7 @@ impl Request { )?; }; - (parse_request_path, quote! { #(#vars,)* }) + (parse_request_path, quote! { #(#path_vars,)* }) } else { (TokenStream::new(), TokenStream::new()) };