From 8ce9c01228bf80cb22a76108356dcd1ce275c2cb Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Sat, 11 Oct 2025 02:08:58 +0200 Subject: [PATCH] feat: Specify (optional) interface name in PartialUserData --- automation_devices/src/lib.rs | 1 + automation_lib/src/lua/traits.rs | 24 ++++++++++++++++++++ automation_macro/src/device.rs | 19 +++++++++++++--- definitions/interfaces.lua | 38 ++++++++++++++++---------------- 4 files changed, 60 insertions(+), 22 deletions(-) diff --git a/automation_devices/src/lib.rs b/automation_devices/src/lib.rs index efd168f..a02bd73 100644 --- a/automation_devices/src/lib.rs +++ b/automation_devices/src/lib.rs @@ -1,3 +1,4 @@ +#![feature(iter_intersperse)] mod air_filter; mod contact_sensor; mod hue_bridge; diff --git a/automation_lib/src/lua/traits.rs b/automation_lib/src/lua/traits.rs index 4d87728..6f61841 100644 --- a/automation_lib/src/lua/traits.rs +++ b/automation_lib/src/lua/traits.rs @@ -4,6 +4,10 @@ use std::ops::Deref; pub trait PartialUserData { fn add_methods>(methods: &mut M); + + fn interface_name() -> Option<&'static str> { + None + } } pub struct Device; @@ -15,6 +19,10 @@ where fn add_methods>(methods: &mut M) { methods.add_async_method("get_id", async |_lua, this, _: ()| Ok(this.get_id())); } + + fn interface_name() -> Option<&'static str> { + Some("DeviceInterface") + } } pub struct OnOff; @@ -34,6 +42,10 @@ where Ok(this.deref().on().await.unwrap()) }); } + + fn interface_name() -> Option<&'static str> { + Some("OnOffInterface") + } } pub struct Brightness; @@ -53,6 +65,10 @@ where Ok(this.brightness().await.unwrap()) }); } + + fn interface_name() -> Option<&'static str> { + Some("BrightnessInterface") + } } pub struct ColorSetting; @@ -77,6 +93,10 @@ where Ok(this.color().await.temperature) }); } + + fn interface_name() -> Option<&'static str> { + Some("ColorSettingInterface") + } } pub struct OpenClose; @@ -96,4 +116,8 @@ where Ok(this.open_percent().await.unwrap()) }); } + + fn interface_name() -> Option<&'static str> { + Some("OpenCloseInterface") + } } diff --git a/automation_macro/src/device.rs b/automation_macro/src/device.rs index 64fcd71..874765f 100644 --- a/automation_macro/src/device.rs +++ b/automation_macro/src/device.rs @@ -128,8 +128,6 @@ impl quote::ToTokens for Implementation { } = &self; let Traits(traits) = traits; - let interfaces: String = traits.iter().map(|tr| format!(", Interface{tr}")).collect(); - tokens.extend(quote! { impl mlua::UserData for #name { fn add_methods>(methods: &mut M) { @@ -165,7 +163,22 @@ impl quote::ToTokens for Implementation { fn generate_header() -> std::option::Option<::std::string::String> { let type_name = ::type_name(); - Some(format!("---@class {type_name}: InterfaceDevice{}\nlocal {type_name}\n", #interfaces)) + let mut output = String::new(); + + let interfaces: String = [ + <::automation_lib::lua::traits::Device as ::automation_lib::lua::traits::PartialUserData<#name>>::interface_name(), + #( + <::automation_lib::lua::traits::#traits as ::automation_lib::lua::traits::PartialUserData<#name>>::interface_name(), + )* + ].into_iter().flatten().intersperse(", ").collect(); + + let interfaces = if interfaces.is_empty() { + "".into() + } else { + format!(": {interfaces}") + }; + + Some(format!("---@class {type_name}{interfaces}\nlocal {type_name}")) } fn generate_members() -> Option { diff --git a/definitions/interfaces.lua b/definitions/interfaces.lua index 222cc4d..c55c117 100644 --- a/definitions/interfaces.lua +++ b/definitions/interfaces.lua @@ -1,42 +1,42 @@ --- @meta ----@class InterfaceDevice -local InterfaceDevice +---@class DeviceInterface +local DeviceInterface ---@return string -function InterfaceDevice:get_id() end +function DeviceInterface:get_id() end ----@class InterfaceOnOff: InterfaceDevice -local InterfaceOnOff +---@class OnOffInterface: DeviceInterface +local OnOffInterface ---@async ---@param on boolean -function InterfaceOnOff:set_on(on) end +function OnOffInterface:set_on(on) end ---@async ---@return boolean -function InterfaceOnOff:on() end +function OnOffInterface:on() end ----@class InterfaceBrightness: InterfaceDevice -local InterfaceBrightness +---@class BrightnessInterface: DeviceInterface +local BrightnessInterface ---@async ---@param brightness integer -function InterfaceBrightness:set_brightness(brightness) end +function BrightnessInterface:set_brightness(brightness) end ---@async ---@return integer -function InterfaceBrightness:brightness() end +function BrightnessInterface:brightness() end ----@class InterfaceColorSetting: InterfaceDevice -local InterfaceColorSetting +---@class ColorSettingInterface: DeviceInterface +local ColorSettingInterface ---@async ---@param temperature integer -function InterfaceColorSetting:set_color_temperature(temperature) end +function ColorSettingInterface:set_color_temperature(temperature) end ---@async ---@return integer -function InterfaceColorSetting:color_temperature() end +function ColorSettingInterface:color_temperature() end ----@class InterfaceOpenClose: InterfaceDevice -local InterfaceOpenClose +---@class OpenCloseInterface: DeviceInterface +local OpenCloseInterface ---@async ---@param open_percent integer -function InterfaceOpenClose:set_open_percent(open_percent) end +function OpenCloseInterface:set_open_percent(open_percent) end ---@async ---@return integer -function InterfaceOpenClose:open_percent() end +function OpenCloseInterface:open_percent() end