From 6b14591d3195224ba75941d90e9b2ec215703cfe Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 18 Nov 2019 22:52:14 +0100 Subject: [PATCH] ruma-api-macros: Rewrite a few leftover errors without spans --- ruma-api-macros/src/api/attribute.rs | 11 +++++----- ruma-api-macros/src/api/mod.rs | 31 ++++++++++++++++++++++------ ruma-api-macros/src/api/request.rs | 9 ++++++-- ruma-api-macros/src/api/response.rs | 2 +- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/ruma-api-macros/src/api/attribute.rs b/ruma-api-macros/src/api/attribute.rs index b0bbd858..c2b771d7 100644 --- a/ruma-api-macros/src/api/attribute.rs +++ b/ruma-api-macros/src/api/attribute.rs @@ -28,16 +28,15 @@ impl Meta { /// # Panics /// /// Panics if the given attribute is a ruma_api attribute, but fails to parse. - pub fn from_attribute(attr: &syn::Attribute) -> Option { + pub fn from_attribute(attr: &syn::Attribute) -> syn::Result> { match &attr.path { syn::Path { leading_colon: None, segments, - } if segments.len() == 1 && segments[0].ident == "ruma_api" => Some( - attr.parse_args() - .expect("ruma_api! could not parse request field attributes"), - ), - _ => None, + } if segments.len() == 1 && segments[0].ident == "ruma_api" => { + attr.parse_args().map(Some) + } + _ => Ok(None), } } } diff --git a/ruma-api-macros/src/api/mod.rs b/ruma-api-macros/src/api/mod.rs index 164543ae..5a4755bd 100644 --- a/ruma-api-macros/src/api/mod.rs +++ b/ruma-api-macros/src/api/mod.rs @@ -46,13 +46,32 @@ impl TryFrom for Api { response: raw_api.response.try_into()?, }; - assert!( - !(res.metadata.method == "GET" - && (res.request.has_body_fields() || res.request.newtype_body_field().is_some())), - "GET endpoints can't have body fields" - ); + let newtype_body_field = res.request.newtype_body_field(); + if res.metadata.method == "GET" + && (res.request.has_body_fields() || newtype_body_field.is_some()) + { + let mut combined_error: Option = None; + let mut add_error = |field| { + let error = syn::Error::new_spanned(field, "GET endpoints can't have body fields"); + if let Some(combined_error_ref) = &mut combined_error { + combined_error_ref.combine(error); + } else { + combined_error = Some(error); + } + }; - Ok(res) + for field in res.request.body_fields() { + add_error(field); + } + + if let Some(field) = newtype_body_field { + add_error(field); + } + + Err(combined_error.unwrap()) + } else { + Ok(res) + } } } diff --git a/ruma-api-macros/src/api/request.rs b/ruma-api-macros/src/api/request.rs index 22eb3eef..b8f95cd5 100644 --- a/ruma-api-macros/src/api/request.rs +++ b/ruma-api-macros/src/api/request.rs @@ -23,7 +23,7 @@ impl Request { let append_stmts = self.header_fields().map(|request_field| { let (field, header_name) = match request_field { RequestField::Header(field, header_name) => (field, header_name), - _ => panic!("expected request field to be header variant"), + _ => unreachable!("expected request field to be header variant"), }; let field_name = &field.ident; @@ -62,6 +62,11 @@ impl Request { self.fields.iter().any(|field| field.is_query()) } + /// Produces an iterator over all the body fields. + pub fn body_fields(&self) -> impl Iterator { + self.fields.iter().filter_map(|field| field.as_body_field()) + } + /// Produces an iterator over all the header fields. pub fn header_fields(&self) -> impl Iterator { self.fields.iter().filter(|field| field.is_header()) @@ -135,7 +140,7 @@ impl TryFrom for Request { let mut header = None; for attr in mem::replace(&mut field.attrs, Vec::new()) { - let meta = match Meta::from_attribute(&attr) { + let meta = match Meta::from_attribute(&attr)? { Some(m) => m, None => { field.attrs.push(attr); diff --git a/ruma-api-macros/src/api/response.rs b/ruma-api-macros/src/api/response.rs index c50566ce..05433d4d 100644 --- a/ruma-api-macros/src/api/response.rs +++ b/ruma-api-macros/src/api/response.rs @@ -105,7 +105,7 @@ impl TryFrom for Response { let mut header = None; for attr in mem::replace(&mut field.attrs, Vec::new()) { - let meta = match Meta::from_attribute(&attr) { + let meta = match Meta::from_attribute(&attr)? { Some(m) => m, None => { field.attrs.push(attr);