Device config is now done through lua
This commit is contained in:
11
automation_macro/Cargo.toml
Normal file
11
automation_macro/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "automation_macro"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.36"
|
||||
syn = "2.0.60"
|
||||
54
automation_macro/src/lib.rs
Normal file
54
automation_macro/src/lib.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, DeriveInput};
|
||||
|
||||
#[proc_macro_derive(LuaDevice, attributes(config))]
|
||||
pub fn lua_device_derive(input: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(input as DeriveInput);
|
||||
|
||||
impl_lua_device_macro(&ast)
|
||||
}
|
||||
|
||||
fn impl_lua_device_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||
let name = &ast.ident;
|
||||
let name_string = name.to_string();
|
||||
// TODO: Handle errors properly
|
||||
// This includes making sure one, and only one config is specified
|
||||
let config = if let syn::Data::Struct(syn::DataStruct {
|
||||
fields: syn::Fields::Named(syn::FieldsNamed { ref named, .. }),
|
||||
..
|
||||
}) = ast.data
|
||||
{
|
||||
named
|
||||
.iter()
|
||||
.find(|&field| {
|
||||
field
|
||||
.attrs
|
||||
.iter()
|
||||
.any(|attr| attr.path().is_ident("config"))
|
||||
})
|
||||
.map(|field| field.ty.clone())
|
||||
.unwrap()
|
||||
} else {
|
||||
unimplemented!()
|
||||
};
|
||||
|
||||
let gen = quote! {
|
||||
impl #name {
|
||||
pub fn register_with_lua(lua: &mlua::Lua) -> mlua::Result<()> {
|
||||
lua.globals().set(#name_string, lua.create_proxy::<#name>()?)
|
||||
}
|
||||
}
|
||||
impl mlua::UserData for #name {
|
||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_function("new", |lua, config: mlua::Value| {
|
||||
let config: #config = mlua::LuaSerdeExt::from_value(lua, config)?;
|
||||
let config: Box<dyn crate::device_manager::DeviceConfig> = Box::new(config);
|
||||
Ok(config)
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gen.into()
|
||||
}
|
||||
Reference in New Issue
Block a user