feat!: Improved attribute parsing in device macro

This commit is contained in:
2025-10-11 01:06:53 +02:00
parent 45485fca37
commit 745a1025bb
5 changed files with 23 additions and 22 deletions

View File

@@ -36,7 +36,7 @@ pub struct Config {
crate::register_type!(Config);
#[derive(Debug, Clone, Device)]
#[device(add_methods(Self::add_methods))]
#[device(add_methods = Self::add_methods)]
pub struct HueBridge {
config: Config,
}

View File

@@ -90,7 +90,7 @@ pub struct Config {
crate::register_type!(Config);
#[derive(Debug, Clone, Device)]
#[device(add_methods(Self::add_methods))]
#[device(add_methods = Self::add_methods)]
pub struct Ntfy {
config: Config,
}

View File

@@ -39,7 +39,7 @@ pub struct State {
}
#[derive(Debug, Clone, Device)]
#[device(add_methods(Self::add_methods))]
#[device(add_methods = Self::add_methods)]
pub struct Presence {
config: Config,
state: Arc<RwLock<State>>,

View File

@@ -4,6 +4,7 @@ use proc_macro2::TokenStream as TokenStream2;
use quote::{ToTokens, quote};
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{Attribute, DeriveInput, Token, parenthesized};
enum Attr {
@@ -11,25 +12,25 @@ enum Attr {
AddMethods(AddMethodsAttr),
}
impl Parse for Attr {
fn parse(input: ParseStream) -> syn::Result<Self> {
let ident: syn::Ident = input.parse()?;
let attr;
_ = parenthesized!(attr in input);
let attr = match ident.to_string().as_str() {
"traits" => Attr::Trait(attr.parse()?),
"add_methods" => Attr::AddMethods(attr.parse()?),
_ => {
return Err(syn::Error::new(
ident.span(),
"Expected 'traits' or 'add_methods'",
));
impl Attr {
fn parse(attr: &Attribute) -> syn::Result<Self> {
let mut parsed = None;
attr.parse_nested_meta(|meta| {
if meta.path.is_ident("traits") {
let input;
_ = parenthesized!(input in meta.input);
parsed = Some(Attr::Trait(input.parse()?));
} else if meta.path.is_ident("add_methods") {
let value = meta.value()?;
parsed = Some(Attr::AddMethods(value.parse()?));
} else {
return Err(syn::Error::new(meta.path.span(), "Unknown attribute"));
}
};
Ok(attr)
Ok(())
})?;
Ok(parsed.expect("Parsed should be set"))
}
}
@@ -249,7 +250,7 @@ pub fn device(input: DeriveInput) -> TokenStream2 {
.attrs
.iter()
.filter(|attr| attr.path().is_ident("device"))
.map(Attribute::parse_args)
.map(Attr::parse)
.try_collect::<Vec<_>>()
{
Ok(attr) => Implementations::from_attr(attr, input.ident),

View File

@@ -64,7 +64,7 @@ pub fn lua_serialize(input: proc_macro::TokenStream) -> proc_macro::TokenStream
/// ```
/// It can then be registered with:
/// ```rust
/// #[device(add_methods(top_secret))]
/// #[device(add_methods = top_secret)]
/// ```
#[proc_macro_derive(Device, attributes(device))]
pub fn device(input: proc_macro::TokenStream) -> proc_macro::TokenStream {