use proc_macro::TokenStream;
use syn::Type;
pub struct MethodAttrs {
pub js_name: Option<String>,
pub state_type: Option<Type>,
pub promise: bool,
pub fast: bool,
}
impl MethodAttrs {
pub fn parse(attr: TokenStream) -> Self {
use std::cell::RefCell;
let js_name: RefCell<Option<String>> = RefCell::new(None);
let state_type: RefCell<Option<Type>> = RefCell::new(None);
let promise: RefCell<bool> = RefCell::new(false);
let fast: RefCell<bool> = RefCell::new(false);
if !attr.is_empty() {
let parser = syn::meta::parser(|meta| {
if meta.path.is_ident("state") {
let value: Type = meta.value()?.parse()?;
*state_type.borrow_mut() = Some(value);
Ok(())
} else if meta.path.is_ident("name") {
let value: syn::LitStr = meta.value()?.parse()?;
*js_name.borrow_mut() = Some(value.value());
Ok(())
} else if meta.path.is_ident("promise") {
*promise.borrow_mut() = true;
Ok(())
} else if meta.path.is_ident("fast") {
*fast.borrow_mut() = true;
Ok(())
} else {
Err(meta.error(
"expected `state = Type`, `name = \"jsName\"`, `promise`, or `fast`",
))
}
});
if syn::parse::Parser::parse(parser, attr.clone()).is_err() {
if let Ok(lit) = syn::parse::<syn::LitStr>(attr) {
*js_name.borrow_mut() = Some(lit.value());
}
}
}
Self {
js_name: js_name.into_inner(),
state_type: state_type.into_inner(),
promise: promise.into_inner(),
fast: fast.into_inner(),
}
}
}