use syn::Ident;
use syn::LitStr;
use syn::Token;
use syn::parse::Parse;
use syn::parse::ParseStream;
extern crate proc_macro;
#[derive(Clone)]
pub struct AttibuteArg {
pub key: String,
pub _eq: String,
pub value: String,
}
impl AttibuteArg {
pub fn suprted_arg_check(key_ident: &proc_macro2::Ident) -> syn::Result<()> {
const SUPORTED_ARGS: &[&str] = &[
"name", "short", ];
let key = format!("{}", key_ident);
let error_message: String = format!(
"
不支持的参数:{key}
已经支持的参数有:
name 命令的实际命令名称。 `函数的名称` 作为 `命令名`。
short 命令的短名称,通常是命令名称的第一个字母。
"
);
if SUPORTED_ARGS.contains(&key.as_ref()) {
return Ok(());
} else {
return Err(syn::Error::new(key_ident.span(), error_message));
}
}
}
impl Parse for AttibuteArg {
fn parse(input: ParseStream) -> syn::Result<Self> {
let key: Ident = input.parse()?; AttibuteArg::suprted_arg_check(&key)?;
let _eq: Token![=] = input.parse()?;
let value: LitStr = input.parse()?;
Ok(AttibuteArg {
key: format!("{}", key),
_eq: "=".to_string(),
value: value.value(),
})
}
}
#[derive(Clone)]
pub struct AttibuteArgList {
pub args: Vec<AttibuteArg>,
}
impl Parse for AttibuteArgList {
fn parse(input: ParseStream) -> syn::Result<Self> {
let args = input.parse_terminated(AttibuteArg::parse, Token![,])?;
Ok(AttibuteArgList {
args: args.into_iter().collect(),
})
}
}
impl AttibuteArgList {
pub fn get(&self, key: &str) -> Option<&AttibuteArg> {
for x in &self.args {
if x.key == key {
return Some(x);
}
}
return None;
}
}