feat!: Improve lua module registration
Instead of having to call all the module registration functions in one place it is possible for each module to register itself in a global registry. During startup all the all the modules will be registered automatically. This does currently have one weakness, to need to ensure that the crate is linked.
This commit is contained in:
12
Cargo.lock
generated
12
Cargo.lock
generated
@@ -100,6 +100,7 @@ dependencies = [
|
||||
"git-version",
|
||||
"google_home",
|
||||
"hostname",
|
||||
"inventory",
|
||||
"mlua",
|
||||
"reqwest",
|
||||
"rumqttc",
|
||||
@@ -128,6 +129,7 @@ dependencies = [
|
||||
"dyn-clone",
|
||||
"eui48",
|
||||
"google_home",
|
||||
"inventory",
|
||||
"mlua",
|
||||
"reqwest",
|
||||
"rumqttc",
|
||||
@@ -151,6 +153,7 @@ dependencies = [
|
||||
"futures",
|
||||
"google_home",
|
||||
"indexmap",
|
||||
"inventory",
|
||||
"mlua",
|
||||
"rumqttc",
|
||||
"serde",
|
||||
@@ -967,6 +970,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inventory"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-uring"
|
||||
version = "0.7.10"
|
||||
|
||||
@@ -34,6 +34,7 @@ google_home = { path = "./google_home/google_home" }
|
||||
google_home_macro = { path = "./google_home/google_home_macro" }
|
||||
hostname = "0.4.1"
|
||||
indexmap = { version = "2.11.0", features = ["serde"] }
|
||||
inventory = "0.3.21"
|
||||
itertools = "0.14.0"
|
||||
json_value_merge = "2.0.1"
|
||||
mlua = { version = "0.11.3", features = [
|
||||
@@ -77,6 +78,7 @@ dotenvy = { workspace = true }
|
||||
git-version = "0.3.9"
|
||||
google_home = { workspace = true }
|
||||
hostname = { workspace = true }
|
||||
inventory = { workspace = true }
|
||||
mlua = { workspace = true }
|
||||
reqwest = { workspace = true }
|
||||
rumqttc = { workspace = true }
|
||||
|
||||
@@ -13,6 +13,7 @@ bytes = { workspace = true }
|
||||
dyn-clone = { workspace = true }
|
||||
eui48 = { workspace = true }
|
||||
google_home = { workspace = true }
|
||||
inventory = { workspace = true }
|
||||
mlua = { workspace = true }
|
||||
reqwest = { workspace = true }
|
||||
rumqttc = { workspace = true }
|
||||
|
||||
@@ -12,6 +12,7 @@ mod wake_on_lan;
|
||||
mod washer;
|
||||
mod zigbee;
|
||||
|
||||
use automation_lib::Module;
|
||||
use automation_lib::device::{Device, LuaDeviceCreate};
|
||||
use zigbee::light::{LightBrightness, LightColorTemperature, LightOnOff};
|
||||
use zigbee::outlet::{OutletOnOff, OutletPower};
|
||||
@@ -36,7 +37,7 @@ macro_rules! register_device {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn register_with_lua(lua: &mlua::Lua) -> mlua::Result<()> {
|
||||
pub fn create_module(lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
||||
register_device!(lua, AirFilter);
|
||||
register_device!(lua, ContactSensor);
|
||||
register_device!(lua, HueBridge);
|
||||
@@ -55,5 +56,8 @@ pub fn register_with_lua(lua: &mlua::Lua) -> mlua::Result<()> {
|
||||
register_device!(lua, WakeOnLAN);
|
||||
register_device!(lua, Washer);
|
||||
|
||||
Ok(())
|
||||
// For now return an empty table and keep the devices in the global table
|
||||
lua.create_table()
|
||||
}
|
||||
|
||||
inventory::submit! {Module::new("devices", create_module)}
|
||||
|
||||
@@ -11,6 +11,7 @@ dyn-clone = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
google_home = { workspace = true }
|
||||
indexmap = { workspace = true }
|
||||
inventory = { workspace = true }
|
||||
mlua = { workspace = true }
|
||||
rumqttc = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
|
||||
@@ -12,3 +12,26 @@ pub mod lua;
|
||||
pub mod messages;
|
||||
pub mod mqtt;
|
||||
pub mod schedule;
|
||||
|
||||
type RegisterFn = fn(lua: &mlua::Lua) -> mlua::Result<mlua::Table>;
|
||||
|
||||
pub struct Module {
|
||||
name: &'static str,
|
||||
register_fn: RegisterFn,
|
||||
}
|
||||
|
||||
impl Module {
|
||||
pub const fn new(name: &'static str, register_fn: RegisterFn) -> Self {
|
||||
Self { name, register_fn }
|
||||
}
|
||||
|
||||
pub const fn get_name(&self) -> &'static str {
|
||||
self.name
|
||||
}
|
||||
|
||||
pub fn register(&self, lua: &mlua::Lua) -> mlua::Result<mlua::Table> {
|
||||
(self.register_fn)(lua)
|
||||
}
|
||||
}
|
||||
|
||||
inventory::collect!(Module);
|
||||
|
||||
13
src/main.rs
13
src/main.rs
@@ -12,8 +12,8 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use ::config::{Environment, File};
|
||||
use automation_lib::config::{FulfillmentConfig, MqttConfig};
|
||||
use automation_lib::device_manager::DeviceManager;
|
||||
use automation_lib::helpers;
|
||||
use automation_lib::mqtt::{self, WrappedAsyncClient};
|
||||
use automation_lib::{Module, helpers};
|
||||
use axum::extract::{FromRef, State};
|
||||
use axum::http::StatusCode;
|
||||
use axum::routing::post;
|
||||
@@ -30,6 +30,9 @@ use web::{ApiError, User};
|
||||
use crate::secret::EnvironmentSecretFile;
|
||||
use crate::version::VERSION;
|
||||
|
||||
// Force automation_devices to link so that it gets registered as a module
|
||||
extern crate automation_devices;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AppState {
|
||||
pub openid_url: String,
|
||||
@@ -138,6 +141,13 @@ async fn app() -> anyhow::Result<()> {
|
||||
})?;
|
||||
lua.globals().set("print", print)?;
|
||||
|
||||
debug!("Loading modules...");
|
||||
for module in inventory::iter::<Module> {
|
||||
debug!(name = module.get_name(), "Registering");
|
||||
let table = module.register(&lua)?;
|
||||
lua.register_module(module.get_name(), table)?;
|
||||
}
|
||||
|
||||
let mqtt = lua.create_table()?;
|
||||
let event_channel = device_manager.event_channel();
|
||||
let mqtt_new = lua.create_function(move |lua, config: mlua::Value| {
|
||||
@@ -174,7 +184,6 @@ async fn app() -> anyhow::Result<()> {
|
||||
utils.set("get_epoch", get_epoch)?;
|
||||
lua.register_module("utils", utils)?;
|
||||
|
||||
automation_devices::register_with_lua(&lua)?;
|
||||
helpers::register_with_lua(&lua)?;
|
||||
|
||||
let entrypoint = Path::new(&config.entrypoint);
|
||||
|
||||
Reference in New Issue
Block a user