feat: Added derive macro to implement IntoLua on structs that implement Serialize

This can be very useful if you want to convert a data struct to a lua
table without having to write the boilerplane (however small it may
be).

It also adds the macro on several state structs so they can be
converted to lua in the upcoming ActionCallback refactor.
This commit is contained in:
2025-09-08 03:18:12 +02:00
parent 3a7f2f9bd7
commit 352654107a
3 changed files with 24 additions and 7 deletions

View File

@@ -10,7 +10,7 @@ use automation_lib::device::{Device, LuaDeviceCreate};
use automation_lib::event::OnMqtt;
use automation_lib::helpers::serialization::state_deserializer;
use automation_lib::mqtt::WrappedAsyncClient;
use automation_macro::{LuaDevice, LuaDeviceConfig};
use automation_macro::{LuaDevice, LuaDeviceConfig, LuaSerialize};
use google_home::device;
use google_home::errors::ErrorCode;
use google_home::traits::{Brightness, Color, ColorSetting, ColorTemperatureRange, OnOff};
@@ -40,7 +40,7 @@ pub struct Config<T: LightState> {
pub client: WrappedAsyncClient,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, Serialize, Deserialize, LuaSerialize)]
pub struct StateOnOff {
#[serde(deserialize_with = "state_deserializer")]
state: bool,
@@ -48,7 +48,7 @@ pub struct StateOnOff {
impl LightState for StateOnOff {}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, Serialize, Deserialize, LuaSerialize)]
pub struct StateBrightness {
#[serde(deserialize_with = "state_deserializer")]
state: bool,
@@ -63,7 +63,7 @@ impl From<StateBrightness> for StateOnOff {
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, Serialize, Deserialize, LuaSerialize)]
pub struct StateColorTemperature {
#[serde(deserialize_with = "state_deserializer")]
state: bool,

View File

@@ -10,7 +10,7 @@ use automation_lib::device::{Device, LuaDeviceCreate};
use automation_lib::event::OnMqtt;
use automation_lib::helpers::serialization::state_deserializer;
use automation_lib::mqtt::WrappedAsyncClient;
use automation_macro::{LuaDevice, LuaDeviceConfig};
use automation_macro::{LuaDevice, LuaDeviceConfig, LuaSerialize};
use google_home::device;
use google_home::errors::ErrorCode;
use google_home::traits::OnOff;
@@ -57,7 +57,7 @@ pub struct Config<T: OutletState> {
pub client: WrappedAsyncClient,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, Serialize, Deserialize, LuaSerialize)]
pub struct StateOnOff {
#[serde(deserialize_with = "state_deserializer")]
state: bool,
@@ -65,7 +65,7 @@ pub struct StateOnOff {
impl OutletState for StateOnOff {}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, Serialize, Deserialize, LuaSerialize)]
pub struct StatePower {
#[serde(deserialize_with = "state_deserializer")]
state: bool,

View File

@@ -3,6 +3,7 @@ mod impl_device;
mod lua_device_config;
use lua_device_config::impl_lua_device_config_macro;
use quote::quote;
use syn::{DeriveInput, parse_macro_input};
use crate::impl_device::impl_device_macro;
@@ -20,3 +21,19 @@ pub fn impl_device(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
impl_device_macro(&ast).into()
}
#[proc_macro_derive(LuaSerialize, attributes(traits))]
pub fn lua_serialize(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let name = &ast.ident;
quote! {
impl ::mlua::IntoLua for #name {
fn into_lua(self, lua: &::mlua::Lua) -> ::mlua::Result<::mlua::Value> {
::mlua::LuaSerdeExt::to_value(lua, &self)
}
}
}
.into()
}