From 4038d8be9593d556412ce9705a324785f7d9e125 Mon Sep 17 00:00:00 2001 From: John Turner Date: Wed, 19 Apr 2023 02:57:03 -0400 Subject: refactored code with if_chain Adding a separate error for the case of an empty attribute list allows the code to be less complicated and gives better diagnostics. Otherwise another nested block would be required. --- src/lib.rs | 66 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 3d0aaa5..9de35a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ pub fn get(input: proc_macro::TokenStream) -> proc_macro::TokenStream { mod get { + use if_chain::if_chain; use proc_macro2::{Span, TokenStream}; use quote::{format_ident, quote, ToTokens}; use syn::{ @@ -133,47 +134,46 @@ mod get { impl TryFrom for GetAttribute { type Error = Box; fn try_from(attr: Attribute) -> Result { - if attr.path().is_ident("get") { - if let Meta::List(meta_list) = &attr.meta { - if let Ok(meta_name_values) = - Punctuated::::parse_terminated - .parse(meta_list.tokens.clone().into()) - { - let get_name_values = meta_name_values - .iter() - .map(|n| n.try_into()) - .collect::, _>>()?; - if let 1..=3 = get_name_values.len() { - return Ok(get_name_values.into_iter().fold( - Self::default(), - |_, g| match g { - GetNameValue::Method(name) => Self { method: Some(name) }, - }, - )); - } - } + if_chain! { + if attr.path().is_ident("get"); + if let Meta::List(list) = &attr.meta; + then { + Ok(Punctuated::::parse_terminated + .parse(list.tokens.clone().into())? + .into_iter() + .map(|n| n.try_into()) + .collect::, _>>() + .map(|v| match v.len() { + 1..=3 => Ok(v), + _ => Err("expected at least 1 name value pair in attribute") + })?? + .into_iter() + .fold(Self::default(), |_, n| match n { + GetNameValue::Method(s) => Self { + method: Some(s), + }, + })) + } else { + Err("failed to parse attribute".into()) } } - Err("failed to parse attribute".into()) } } - // The same applies here. - - impl<'a> TryFrom<&'a MetaNameValue> for GetNameValue { + impl TryFrom for GetNameValue { type Error = Box; - fn try_from(meta: &'a MetaNameValue) -> Result { - if let Some(name) = meta.path.get_ident().map(|i| i.to_string()) { - if let Expr::Lit(expr_lit) = &meta.value { - if let Lit::Str(s) = &expr_lit.lit { - let value = s.value(); - if let "method" = name.as_str() { - return Ok(Self::Method(value)); - }; - } + fn try_from(meta: MetaNameValue) -> Result { + if_chain! { + if let Some(name) = meta.path.get_ident().map(|ident| ident.to_string()); + if let Expr::Lit(expr) = &meta.value; + if let Lit::Str(s) = &expr.lit; + if let "method" = name.as_str(); + then { + Ok(Self::Method(s.value())) + } else { + Err("invalid name value list in attribute".into()) } } - Err("invalid name value list in attribute".into()) } } } -- cgit v1.2.3