diff --git a/automation_devices/src/zigbee/light.rs b/automation_devices/src/zigbee/light.rs index 730dafa..d5ba0ed 100644 --- a/automation_devices/src/zigbee/light.rs +++ b/automation_devices/src/zigbee/light.rs @@ -89,9 +89,9 @@ impl From for StateBrightness { } #[derive(Debug, Clone, Device)] -#[device(traits(OnOff for , , ))] -#[device(traits(Brightness for , ))] -#[device(traits(ColorSetting for ))] +#[device(traits(OnOff for LightOnOff, LightBrightness, LightColorTemperature))] +#[device(traits(Brightness for LightBrightness, LightColorTemperature))] +#[device(traits(ColorSetting for LightColorTemperature))] pub struct Light { config: Config, @@ -144,7 +144,7 @@ impl Device for Light { } #[async_trait] -impl OnMqtt for Light { +impl OnMqtt for LightOnOff { async fn on_mqtt(&self, message: Publish) { // Check if the message is from the device itself or from a remote if matches(&message.topic, &self.config.mqtt.topic) { @@ -177,7 +177,7 @@ impl OnMqtt for Light { } #[async_trait] -impl OnMqtt for Light { +impl OnMqtt for LightBrightness { async fn on_mqtt(&self, message: Publish) { // Check if the message is from the deviec itself or from a remote if matches(&message.topic, &self.config.mqtt.topic) { @@ -216,7 +216,7 @@ impl OnMqtt for Light { } #[async_trait] -impl OnMqtt for Light { +impl OnMqtt for LightColorTemperature { async fn on_mqtt(&self, message: Publish) { // Check if the message is from the deviec itself or from a remote if matches(&message.topic, &self.config.mqtt.topic) { diff --git a/automation_devices/src/zigbee/outlet.rs b/automation_devices/src/zigbee/outlet.rs index 220418e..ddf640d 100644 --- a/automation_devices/src/zigbee/outlet.rs +++ b/automation_devices/src/zigbee/outlet.rs @@ -81,7 +81,7 @@ impl From for StateOnOff { } #[derive(Debug, Clone, Device)] -#[device(traits(OnOff for , ))] +#[device(traits(OnOff for OutletOnOff, OutletPower))] pub struct Outlet { config: Config, @@ -131,7 +131,7 @@ impl Device for Outlet { } #[async_trait] -impl OnMqtt for Outlet { +impl OnMqtt for OutletOnOff { async fn on_mqtt(&self, message: Publish) { // Check if the message is from the device itself or from a remote if matches(&message.topic, &self.config.mqtt.topic) { @@ -164,7 +164,7 @@ impl OnMqtt for Outlet { } #[async_trait] -impl OnMqtt for Outlet { +impl OnMqtt for OutletPower { async fn on_mqtt(&self, message: Publish) { // Check if the message is from the deviec itself or from a remote if matches(&message.topic, &self.config.mqtt.topic) { diff --git a/automation_macro/src/device.rs b/automation_macro/src/device.rs index 99058d3..b886436 100644 --- a/automation_macro/src/device.rs +++ b/automation_macro/src/device.rs @@ -35,14 +35,14 @@ impl Parse for Attr { struct TraitAttr { traits: Traits, - generics: Generics, + aliases: Aliases, } impl Parse for TraitAttr { fn parse(input: ParseStream) -> syn::Result { Ok(Self { traits: input.parse()?, - generics: input.parse()?, + aliases: input.parse()?, }) } } @@ -78,15 +78,15 @@ impl ToTokens for Traits { } #[derive(Default)] -struct Generics(Vec); +struct Aliases(Vec); -impl Generics { - fn has_generics(&self) -> bool { +impl Aliases { + fn has_aliases(&self) -> bool { !self.0.is_empty() } } -impl Parse for Generics { +impl Parse for Aliases { fn parse(input: ParseStream) -> syn::Result { if !input.peek(Token![for]) { if input.is_empty() { @@ -100,7 +100,7 @@ impl Parse for Generics { input .call(Punctuated::<_, Token![,]>::parse_separated_nonempty) - .map(|generics| generics.into_iter().collect()) + .map(|aliases| aliases.into_iter().collect()) .map(Self) } } @@ -125,7 +125,7 @@ impl ToTokens for AddMethodsAttr { } struct Implementation { - generics: Option, + name: syn::Ident, traits: Traits, add_methods: Vec, } @@ -133,13 +133,13 @@ struct Implementation { impl quote::ToTokens for Implementation { fn to_tokens(&self, tokens: &mut TokenStream2) { let Self { - generics, + name, traits, add_methods, } = &self; tokens.extend(quote! { - #generics { + impl mlua::UserData for #name { fn add_methods>(methods: &mut M) { methods.add_async_function("new", async |_lua, config| { let device: Self = LuaDeviceCreate::create(config) @@ -169,18 +169,18 @@ impl quote::ToTokens for Implementation { struct Implementations(Vec); -impl From> for Implementations { - fn from(attributes: Vec) -> Self { +impl Implementations { + fn from_attr(attributes: Vec, name: syn::Ident) -> Self { let mut add_methods = Vec::new(); let mut all = Traits::default(); let mut implementations: HashMap<_, Traits> = HashMap::new(); for attribute in attributes { match attribute { Attr::Trait(attribute) => { - if attribute.generics.has_generics() { - for generic in &attribute.generics.0 { + if attribute.aliases.has_aliases() { + for alias in &attribute.aliases.0 { implementations - .entry(Some(generic.clone())) + .entry(Some(alias.clone())) .or_default() .extend(&attribute.traits); } @@ -203,8 +203,8 @@ impl From> for Implementations { Self( implementations .into_iter() - .map(|(generics, traits)| Implementation { - generics, + .map(|(alias, traits)| Implementation { + name: alias.unwrap_or(name.clone()), traits, add_methods: add_methods.clone(), }) @@ -213,9 +213,7 @@ impl From> for Implementations { } } -pub fn device(input: &DeriveInput) -> TokenStream2 { - let name = &input.ident; - +pub fn device(input: DeriveInput) -> TokenStream2 { let Implementations(imp) = match input .attrs .iter() @@ -223,13 +221,13 @@ pub fn device(input: &DeriveInput) -> TokenStream2 { .map(Attribute::parse_args) .try_collect::>() { - Ok(result) => result.into(), + Ok(attr) => Implementations::from_attr(attr, input.ident), Err(err) => return err.into_compile_error(), }; quote! { #( - impl mlua::UserData for #name #imp + #imp )* } } diff --git a/automation_macro/src/lib.rs b/automation_macro/src/lib.rs index 3e03abe..162ff30 100644 --- a/automation_macro/src/lib.rs +++ b/automation_macro/src/lib.rs @@ -69,5 +69,5 @@ pub fn lua_serialize(input: proc_macro::TokenStream) -> proc_macro::TokenStream #[proc_macro_derive(Device, attributes(device))] pub fn device(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let ast = parse_macro_input!(input as DeriveInput); - device::device(&ast).into() + device::device(ast).into() }