feat: Specify (optional) interface name in PartialUserData

This commit is contained in:
2025-10-11 02:08:58 +02:00
parent 006a561307
commit 4b76bde2a6
4 changed files with 60 additions and 22 deletions

View File

@@ -1,3 +1,4 @@
#![feature(iter_intersperse)]
mod air_filter; mod air_filter;
mod contact_sensor; mod contact_sensor;
mod hue_bridge; mod hue_bridge;

View File

@@ -4,6 +4,10 @@ use std::ops::Deref;
pub trait PartialUserData<T> { pub trait PartialUserData<T> {
fn add_methods<M: mlua::UserDataMethods<T>>(methods: &mut M); fn add_methods<M: mlua::UserDataMethods<T>>(methods: &mut M);
fn interface_name() -> Option<&'static str> {
None
}
} }
pub struct Device; pub struct Device;
@@ -15,6 +19,10 @@ where
fn add_methods<M: mlua::UserDataMethods<T>>(methods: &mut M) { fn add_methods<M: mlua::UserDataMethods<T>>(methods: &mut M) {
methods.add_async_method("get_id", async |_lua, this, _: ()| Ok(this.get_id())); methods.add_async_method("get_id", async |_lua, this, _: ()| Ok(this.get_id()));
} }
fn interface_name() -> Option<&'static str> {
Some("DeviceInterface")
}
} }
pub struct OnOff; pub struct OnOff;
@@ -34,6 +42,10 @@ where
Ok(this.deref().on().await.unwrap()) Ok(this.deref().on().await.unwrap())
}); });
} }
fn interface_name() -> Option<&'static str> {
Some("OnOffInterface")
}
} }
pub struct Brightness; pub struct Brightness;
@@ -53,6 +65,10 @@ where
Ok(this.brightness().await.unwrap()) Ok(this.brightness().await.unwrap())
}); });
} }
fn interface_name() -> Option<&'static str> {
Some("BrightnessInterface")
}
} }
pub struct ColorSetting; pub struct ColorSetting;
@@ -77,6 +93,10 @@ where
Ok(this.color().await.temperature) Ok(this.color().await.temperature)
}); });
} }
fn interface_name() -> Option<&'static str> {
Some("ColorSettingInterface")
}
} }
pub struct OpenClose; pub struct OpenClose;
@@ -96,4 +116,8 @@ where
Ok(this.open_percent().await.unwrap()) Ok(this.open_percent().await.unwrap())
}); });
} }
fn interface_name() -> Option<&'static str> {
Some("OpenCloseInterface")
}
} }

View File

@@ -128,8 +128,6 @@ impl quote::ToTokens for Implementation {
} = &self; } = &self;
let Traits(traits) = traits; let Traits(traits) = traits;
let interfaces: String = traits.iter().map(|tr| format!(", Interface{tr}")).collect();
tokens.extend(quote! { tokens.extend(quote! {
impl mlua::UserData for #name { impl mlua::UserData for #name {
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) { fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
@@ -165,7 +163,22 @@ impl quote::ToTokens for Implementation {
fn generate_header() -> std::option::Option<::std::string::String> { fn generate_header() -> std::option::Option<::std::string::String> {
let type_name = <Self as ::lua_typed::Typed>::type_name(); let type_name = <Self as ::lua_typed::Typed>::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<String> { fn generate_members() -> Option<String> {

View File

@@ -1,42 +1,42 @@
--- @meta --- @meta
---@class InterfaceDevice ---@class DeviceInterface
local InterfaceDevice local DeviceInterface
---@return string ---@return string
function InterfaceDevice:get_id() end function DeviceInterface:get_id() end
---@class InterfaceOnOff: InterfaceDevice ---@class OnOffInterface: DeviceInterface
local InterfaceOnOff local OnOffInterface
---@async ---@async
---@param on boolean ---@param on boolean
function InterfaceOnOff:set_on(on) end function OnOffInterface:set_on(on) end
---@async ---@async
---@return boolean ---@return boolean
function InterfaceOnOff:on() end function OnOffInterface:on() end
---@class InterfaceBrightness: InterfaceDevice ---@class BrightnessInterface: DeviceInterface
local InterfaceBrightness local BrightnessInterface
---@async ---@async
---@param brightness integer ---@param brightness integer
function InterfaceBrightness:set_brightness(brightness) end function BrightnessInterface:set_brightness(brightness) end
---@async ---@async
---@return integer ---@return integer
function InterfaceBrightness:brightness() end function BrightnessInterface:brightness() end
---@class InterfaceColorSetting: InterfaceDevice ---@class ColorSettingInterface: DeviceInterface
local InterfaceColorSetting local ColorSettingInterface
---@async ---@async
---@param temperature integer ---@param temperature integer
function InterfaceColorSetting:set_color_temperature(temperature) end function ColorSettingInterface:set_color_temperature(temperature) end
---@async ---@async
---@return integer ---@return integer
function InterfaceColorSetting:color_temperature() end function ColorSettingInterface:color_temperature() end
---@class InterfaceOpenClose: InterfaceDevice ---@class OpenCloseInterface: DeviceInterface
local InterfaceOpenClose local OpenCloseInterface
---@async ---@async
---@param open_percent integer ---@param open_percent integer
function InterfaceOpenClose:set_open_percent(open_percent) end function OpenCloseInterface:set_open_percent(open_percent) end
---@async ---@async
---@return integer ---@return integer
function InterfaceOpenClose:open_percent() end function OpenCloseInterface:open_percent() end