From cf6367d441417e84866468533d422de6cee29da2 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 20 Feb 2024 18:02:50 +0000 Subject: [PATCH] Reduce duplication by introducing WherePredicatesOrBool::from_lit Parse for WherePredicatesOrBool and meta_name_value_2_where_predicates_bool each had a version of this code. I compared each match branch while unifying them, and the two behaviours were identical. This commit introduces an error handling change for literal that's neither a boolean nor a string: previously Parse for WherePredicatesOrBool would feed it to parse_terminated expecting a WherePredicate, which would fail; and meta_name_value_2_where_predicates_bool would pass it through to its general error handler. Now we make a bespoke error for this weird case. (I'm not sure why we have both WherePredicatesOrBool and Bound. I think they could be unified.) --- src/common/where_predicates_bool.rs | 49 +++++++++++++---------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/common/where_predicates_bool.rs b/src/common/where_predicates_bool.rs index 614c34b..a72e6b8 100644 --- a/src/common/where_predicates_bool.rs +++ b/src/common/where_predicates_bool.rs @@ -18,21 +18,30 @@ pub(crate) enum WherePredicatesOrBool { Bool(bool), } +impl WherePredicatesOrBool { + fn from_lit(lit: &Lit) -> syn::Result { + Ok(match lit { + Lit::Bool(lit) => Self::Bool(lit.value), + Lit::Str(lit) => match lit.parse_with(WherePredicates::parse_terminated) { + Ok(where_predicates) => Self::WherePredicates(where_predicates), + Err(_) if lit.value().is_empty() => Self::Bool(false), + Err(error) => return Err(error), + }, + other => { + return Err(syn::Error::new( + other.span(), + "unexpected kind of literal (only boolean or string allowed)", + )) + }, + }) + } +} + impl Parse for WherePredicatesOrBool { #[inline] fn parse(input: ParseStream) -> syn::Result { if let Ok(lit) = input.parse::() { - match lit { - Lit::Bool(lit) => return Ok(Self::Bool(lit.value)), - Lit::Str(lit) => { - return match lit.parse_with(WherePredicates::parse_terminated) { - Ok(where_predicates) => Ok(Self::WherePredicates(where_predicates)), - Err(_) if lit.value().is_empty() => Ok(Self::Bool(false)), - Err(error) => Err(error), - } - }, - _ => (), - } + return Self::from_lit(&lit); } Ok(Self::WherePredicates(input.parse_terminated(WherePredicate::parse, Token![,])?)) @@ -44,23 +53,7 @@ pub(crate) fn meta_name_value_2_where_predicates_bool( name_value: &MetaNameValue, ) -> syn::Result { if let Expr::Lit(lit) = &name_value.value { - match &lit.lit { - Lit::Str(lit) => match lit.parse_with(WherePredicates::parse_terminated) { - Ok(where_predicates) => { - return Ok(WherePredicatesOrBool::WherePredicates(where_predicates)) - }, - Err(_) if lit.value().is_empty() => { - return Ok(WherePredicatesOrBool::Bool(false)); - }, - Err(error) => { - return Err(error); - }, - }, - Lit::Bool(lit) => { - return Ok(WherePredicatesOrBool::Bool(lit.value)); - }, - _ => (), - } + return WherePredicatesOrBool::from_lit(&lit.lit); } Err(syn::Error::new(