use quote::ToTokens; use syn::{parse_quote, punctuated::Punctuated, token::Comma, Expr, Lit, Meta, Result}; fn transform_recursive(features: &[&str], input: Meta) -> Result { match input { Meta::NameValue(nv) => { if nv.path == parse_quote!(target_feature) { if let Expr::Lit(lit) = &nv.value { if let Lit::Str(lit) = &lit.lit { if features.contains(&lit.value().as_str()) { return Ok(parse_quote! { all() }); } } } } Ok(Meta::NameValue(nv)) } Meta::List(mut list) => { let mut metas = list.parse_args_with(Punctuated::::parse_terminated)?; for meta in metas.iter_mut() { *meta = transform_recursive(features, meta.clone())?; } list.tokens = metas.into_token_stream(); Ok(Meta::List(list)) } input => Ok(input), } } pub(crate) fn transform(mut input: Punctuated) -> Result { assert_eq!(input.len(), 2); let features = if let Expr::Lit(features) = &input[0].require_name_value()?.value { if let Lit::Str(features) = &features.lit { Some(features.value()) } else { None } } else { None }; let features = features.expect("couldn't parse first argument"); let features = features.split(',').collect::>(); transform_recursive(&features, input.pop().unwrap().into_value()) }