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); crate::register_type!(Config);
#[derive(Debug, Clone, Device)] #[derive(Debug, Clone, Device)]
#[device(add_methods(Self::add_methods))] #[device(add_methods = Self::add_methods)]
pub struct HueBridge { pub struct HueBridge {
config: Config, config: Config,
} }

View File

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

View File

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

View File

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