utils.rs (1961B)
1 use proc_macro::TokenStream; 2 use quote::quote; 3 use syn::spanned::Spanned; 4 5 pub(crate) fn get_arg<'a>( 6 input_span: proc_macro2::Span, 7 args: syn::AttributeArgs, 8 arg: &'a str, 9 expected: &'a str, 10 expected_args: usize, 11 ) -> Result<syn::LitStr, TokenStream> { 12 if args.len() == expected_args { 13 let meta = args 14 .iter() 15 .filter_map(|x| { 16 if let syn::NestedMeta::Meta(ref meta) = x { 17 if meta.path().is_ident(&arg) { 18 return Some(meta); 19 } 20 } 21 None 22 }) 23 .next(); 24 if let Some(meta) = meta { 25 if let syn::Meta::NameValue(ref meta) = meta { 26 let meta_lit = meta.lit.clone(); 27 return match meta_lit { 28 syn::Lit::Str(s) => Ok(s), 29 _ => { 30 let error = syn::Error::new( 31 meta.lit.span(), 32 format!( 33 "expected `{}`\n\nThe field '{}' needs to be a str literal!", 34 expected, arg 35 ), 36 ) 37 .to_compile_error(); 38 Err(quote! {#error}.into()) 39 } 40 }; 41 } 42 } else { 43 let error = syn::Error::new( 44 meta.span(), 45 format!( 46 "1expected `{}`\n\nThe field '{}' is required!", 47 expected, arg 48 ), 49 ) 50 .to_compile_error(); 51 return Err(quote! {#error}.into()); 52 } 53 } 54 let error = syn::Error::new( 55 input_span, 56 format!( 57 "expected `{}` but not enough arguments where provided.", 58 expected 59 ), 60 ) 61 .to_compile_error(); 62 Err(quote! {#error}.into()) 63 }