Made the impl_device macro more explicit about the implemented traits
This also converts impl_device into a procedural macro and get rid of a lot of "magic" that was happening.
This commit is contained in:
@@ -23,4 +23,3 @@ tokio-cron-scheduler = { workspace = true }
|
||||
mlua = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
dyn-clone = { workspace = true }
|
||||
impls = { workspace = true }
|
||||
|
||||
@@ -7,51 +7,6 @@ use mlua::ObjectLike;
|
||||
|
||||
use crate::event::{OnDarkness, OnMqtt, OnNotification, OnPresence};
|
||||
|
||||
// TODO: Make this a proper macro
|
||||
macro_rules! impl_device {
|
||||
($device:ty) => {
|
||||
impl mlua::UserData for $device {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_async_function("new", |_lua, config| async {
|
||||
let device: $device = LuaDeviceCreate::create(config)
|
||||
.await
|
||||
.map_err(mlua::ExternalError::into_lua_err)?;
|
||||
|
||||
Ok(device)
|
||||
});
|
||||
|
||||
methods.add_method("__box", |_lua, this, _: ()| {
|
||||
let b: Box<dyn Device> = Box::new(this.clone());
|
||||
Ok(b)
|
||||
});
|
||||
|
||||
methods.add_async_method("get_id", |_lua, this, _: ()| async move { Ok(this.get_id()) });
|
||||
|
||||
if impls::impls!($device: google_home::traits::OnOff) {
|
||||
methods.add_async_method("set_on", |_lua, this, on: bool| async move {
|
||||
(this.deref().cast() as Option<&dyn google_home::traits::OnOff>)
|
||||
.expect("Cast should be valid")
|
||||
.set_on(on)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_async_method("is_on", |_lua, this, _: ()| async move {
|
||||
Ok((this.deref().cast() as Option<&dyn google_home::traits::OnOff>)
|
||||
.expect("Cast should be valid")
|
||||
.on()
|
||||
.await
|
||||
.unwrap())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
pub(crate) use impl_device;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait LuaDeviceCreate {
|
||||
type Config;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(specialization)]
|
||||
|
||||
pub mod action_callback;
|
||||
pub mod config;
|
||||
@@ -8,6 +7,7 @@ pub mod device_manager;
|
||||
pub mod error;
|
||||
pub mod event;
|
||||
pub mod helpers;
|
||||
pub mod lua;
|
||||
pub mod messages;
|
||||
pub mod mqtt;
|
||||
pub mod ntfy;
|
||||
|
||||
1
automation_lib/src/lua/mod.rs
Normal file
1
automation_lib/src/lua/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod traits;
|
||||
83
automation_lib/src/lua/traits.rs
Normal file
83
automation_lib/src/lua/traits.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
// TODO: Enable and disable functions based on query_only and command_only
|
||||
|
||||
pub trait OnOff {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M)
|
||||
where
|
||||
Self: Sized + google_home::traits::OnOff + 'static,
|
||||
{
|
||||
methods.add_async_method("set_on", |_lua, this, on: bool| async move {
|
||||
this.deref().set_on(on).await.unwrap();
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_async_method("on", |_lua, this, ()| async move {
|
||||
Ok(this.deref().on().await.unwrap())
|
||||
});
|
||||
}
|
||||
}
|
||||
impl<T> OnOff for T where T: google_home::traits::OnOff {}
|
||||
|
||||
pub trait Brightness {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M)
|
||||
where
|
||||
Self: Sized + google_home::traits::Brightness + 'static,
|
||||
{
|
||||
methods.add_async_method("set_brightness", |_lua, this, brightness: u8| async move {
|
||||
this.set_brightness(brightness).await.unwrap();
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_async_method("brightness", |_lua, this, _: ()| async move {
|
||||
Ok(this.brightness().await.unwrap())
|
||||
});
|
||||
}
|
||||
}
|
||||
impl<T> Brightness for T where T: google_home::traits::Brightness {}
|
||||
|
||||
pub trait ColorSetting {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M)
|
||||
where
|
||||
Self: Sized + google_home::traits::ColorSetting + 'static,
|
||||
{
|
||||
methods.add_async_method(
|
||||
"set_color_temperature",
|
||||
|_lua, this, temperature: u32| async move {
|
||||
this.set_color(google_home::traits::Color { temperature })
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
|
||||
methods.add_async_method("color_temperature", |_lua, this, ()| async move {
|
||||
Ok(this.color().await.temperature)
|
||||
});
|
||||
}
|
||||
}
|
||||
impl<T> ColorSetting for T where T: google_home::traits::ColorSetting {}
|
||||
|
||||
pub trait OpenClose {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M)
|
||||
where
|
||||
Self: Sized + google_home::traits::OpenClose + 'static,
|
||||
{
|
||||
methods.add_async_method(
|
||||
"set_open_percent",
|
||||
|_lua, this, open_percent: u8| async move {
|
||||
this.set_open_percent(open_percent).await.unwrap();
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
|
||||
methods.add_async_method("open_percent", |_lua, this, _: ()| async move {
|
||||
Ok(this.open_percent().await.unwrap())
|
||||
});
|
||||
}
|
||||
}
|
||||
impl<T> OpenClose for T where T: google_home::traits::OpenClose {}
|
||||
@@ -1,15 +1,13 @@
|
||||
use std::collections::HashMap;
|
||||
use std::convert::Infallible;
|
||||
use std::ops::Deref;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use automation_cast::Cast;
|
||||
use automation_macro::LuaDeviceConfig;
|
||||
use automation_macro::{LuaDeviceConfig, impl_device};
|
||||
use serde::Serialize;
|
||||
use serde_repr::*;
|
||||
use tracing::{error, trace, warn};
|
||||
|
||||
use crate::device::{Device, LuaDeviceCreate, impl_device};
|
||||
use crate::device::{Device, LuaDeviceCreate};
|
||||
use crate::event::{self, Event, EventChannel, OnNotification, OnPresence};
|
||||
|
||||
#[derive(Debug, Serialize_repr, Clone, Copy)]
|
||||
@@ -125,7 +123,6 @@ pub struct Config {
|
||||
pub struct Ntfy {
|
||||
config: Config,
|
||||
}
|
||||
|
||||
impl_device!(Ntfy);
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use automation_cast::Cast;
|
||||
use automation_macro::LuaDeviceConfig;
|
||||
use automation_macro::{LuaDeviceConfig, impl_device};
|
||||
use rumqttc::Publish;
|
||||
use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use tracing::{debug, trace, warn};
|
||||
|
||||
use crate::config::MqttDeviceConfig;
|
||||
use crate::device::{Device, LuaDeviceCreate, impl_device};
|
||||
use crate::device::{Device, LuaDeviceCreate};
|
||||
use crate::event::{self, Event, EventChannel, OnMqtt};
|
||||
use crate::messages::PresenceMessage;
|
||||
use crate::mqtt::WrappedAsyncClient;
|
||||
@@ -38,6 +36,7 @@ pub struct Presence {
|
||||
config: Config,
|
||||
state: Arc<RwLock<State>>,
|
||||
}
|
||||
impl_device!(Presence);
|
||||
|
||||
impl Presence {
|
||||
async fn state(&self) -> RwLockReadGuard<'_, State> {
|
||||
@@ -49,8 +48,6 @@ impl Presence {
|
||||
}
|
||||
}
|
||||
|
||||
impl_device!(Presence);
|
||||
|
||||
#[async_trait]
|
||||
impl LuaDeviceCreate for Presence {
|
||||
type Config = Config;
|
||||
|
||||
Reference in New Issue
Block a user