1 use std::str::FromStr; 2 3 use crate::params_style::ParamStyle; 4 use crate::rpc_attr::path_eq_str; 5 6 const CLIENT_META_WORD: &str = "client"; 7 const SERVER_META_WORD: &str = "server"; 8 const PARAMS_META_KEY: &str = "params"; 9 10 #[derive(Debug)] 11 pub struct DeriveOptions { 12 pub enable_client: bool, 13 pub enable_server: bool, 14 pub params_style: ParamStyle, 15 } 16 17 impl DeriveOptions { new(enable_client: bool, enable_server: bool, params_style: ParamStyle) -> Self18 pub fn new(enable_client: bool, enable_server: bool, params_style: ParamStyle) -> Self { 19 DeriveOptions { 20 enable_client, 21 enable_server, 22 params_style, 23 } 24 } 25 try_from(args: syn::AttributeArgs) -> Result<Self, syn::Error>26 pub fn try_from(args: syn::AttributeArgs) -> Result<Self, syn::Error> { 27 let mut options = DeriveOptions::new(false, false, ParamStyle::default()); 28 for arg in args { 29 if let syn::NestedMeta::Meta(meta) = arg { 30 match meta { 31 syn::Meta::Path(ref p) => { 32 match p 33 .get_ident() 34 .ok_or(syn::Error::new_spanned( 35 p, 36 format!("Expecting identifier `{}` or `{}`", CLIENT_META_WORD, SERVER_META_WORD), 37 ))? 38 .to_string() 39 .as_ref() 40 { 41 CLIENT_META_WORD => options.enable_client = true, 42 SERVER_META_WORD => options.enable_server = true, 43 _ => {} 44 }; 45 } 46 syn::Meta::NameValue(nv) => { 47 if path_eq_str(&nv.path, PARAMS_META_KEY) { 48 if let syn::Lit::Str(ref lit) = nv.lit { 49 options.params_style = ParamStyle::from_str(&lit.value()) 50 .map_err(|e| syn::Error::new_spanned(nv.clone(), e))?; 51 } 52 } else { 53 return Err(syn::Error::new_spanned(nv, "Unexpected RPC attribute key")); 54 } 55 } 56 _ => return Err(syn::Error::new_spanned(meta, "Unexpected use of RPC attribute macro")), 57 } 58 } 59 } 60 if !options.enable_client && !options.enable_server { 61 // if nothing provided default to both 62 options.enable_client = true; 63 options.enable_server = true; 64 } 65 if options.enable_server && options.params_style == ParamStyle::Named { 66 // This is not allowed at this time 67 panic!("Server code generation only supports `params = \"positional\"` (default) or `params = \"raw\" at this time.") 68 } 69 Ok(options) 70 } 71 } 72