Fully add a lua api #11

Merged
antifallobst merged 19 commits from commands into master 2023-07-21 18:57:04 +00:00
9 changed files with 74 additions and 80 deletions
Showing only changes of commit c3a2b2d566 - Show all commits

49
Cargo.lock generated
View File

@ -1533,6 +1533,23 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "mlua"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07366ed2cd22a3b000aed076e2b68896fb46f06f1f5786c5962da73c0af01577"
dependencies = [
"bstr",
"cc",
"futures-core",
"futures-task",
"futures-util",
"num-traits",
"once_cell",
"pkg-config",
"rustc-hash",
]
[[package]] [[package]]
name = "native-tls" name = "native-tls"
version = "0.2.11" version = "0.2.11"
@ -2125,30 +2142,6 @@ dependencies = [
"winreg", "winreg",
] ]
[[package]]
name = "rlua"
version = "0.19.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d33e5ba15c3d43178f283ed5863d4531e292fc0e56fb773f3bea45f18e3a42a"
dependencies = [
"bitflags",
"bstr",
"libc",
"num-traits",
"rlua-lua54-sys",
]
[[package]]
name = "rlua-lua54-sys"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7aafabafe1895cb4a2be81a56d7ff3d46bf4b5d2f9cfdbea2ed404cdabe96474"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "ruma" name = "ruma"
version = "0.7.4" version = "0.7.4"
@ -2254,6 +2247,12 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.37.23" version = "0.37.23"
@ -2706,7 +2705,7 @@ dependencies = [
"indexmap 2.0.0", "indexmap 2.0.0",
"lua_macros", "lua_macros",
"matrix-sdk", "matrix-sdk",
"rlua", "mlua",
"serde", "serde",
"tokio", "tokio",
"tokio-util", "tokio-util",

View File

@ -18,4 +18,4 @@ tokio-util = "0.7"
serde = "1.0" serde = "1.0"
cli-log = "2.0" cli-log = "2.0"
indexmap = "2.0.0" indexmap = "2.0.0"
rlua = "0.19.7" mlua = { version = "0.8.9", features = ["lua54", "async"] }

View File

@ -55,6 +55,7 @@
]; ];
buildInputs = with pkgs; [ buildInputs = with pkgs; [
openssl openssl
lua54Packages.stdlib
]; ];
craneBuild = craneLib.buildPackage { craneBuild = craneLib.buildPackage {

View File

@ -97,35 +97,38 @@ fn append_tx_send_code(input: &mut syn::ItemFn) -> &mut syn::ItemFn {
} }
_ => unimplemented!("Only for path types"), _ => unimplemented!("Only for path types"),
}; };
match return_type { let send_data = match return_type {
ReturnType::Default => { ReturnType::Default => {
quote! { quote! {
{ {
let tx: std::sync::mpsc::Sender<crate::app::events::event_types::Event> = Event::CommandEvent(Command::#function_name_pascal)
context
.named_registry_value("sender_for_ci_commands")
.expect("This exists, it was set before");
tx
.send(Event::CommandEvent(Command::#function_name_pascal))
.expect("This should work, as the reciever is not dropped");
} }
} }
} }
ReturnType::Type(_, _) => { ReturnType::Type(_, _) => {
quote! { quote! {
{ {
let tx: std::sync::mpsc::Sender<crate::app::events::event_types::Event> = Event::CommandEvent(Command::#function_name_pascal(input_str))
context
.named_registry_value("sender_for_ci_commands")
.expect("This exists, it was set before");
tx
.send(Event::CommandEvent(Command::#function_name_pascal(input_str)))
.expect("This should work, as the reciever is not dropped");
} }
} }
} }
};
quote! {
{
let tx: std::sync::Arc<std::sync::Mutex<tokio::sync::mpsc::Sender<crate::app::events::event_types::Event>>> =
lua
.named_registry_value("sender_for_ci_commands")
.expect("This exists, it was set before");
tx
// FIXME: This is sync code, it needs to be run in a blocking allowed
// executor
.lock()
.expect("This should work, as only one function is executed. It wil however fail, when concurrency is added");
.send(#send_data)
.await
.expect("This should work, as the reciever is not dropped");
}
} }
} }
}; };

View File

@ -22,10 +22,10 @@ pub fn generate_generate_ci_function(input: &syn::DeriveInput) -> TokenStream2 {
.expect("These are only the named field, thus they all should have a name."); .expect("These are only the named field, thus they all should have a name.");
functions_to_generate.push(quote! { functions_to_generate.push(quote! {
#[ci_command] #[ci_command]
fn #function_name(context: Context, input_str: String) -> Result<(), rlua::Error> { async fn #function_name(lua: &mlua::Lua, input_str: String) -> Result<(), mlua::Error> {
Ok(()) Ok(())
} }
}); });
generate_ci_part(field) generate_ci_part(field)
} else { } else {
generate_ci_part(field) generate_ci_part(field)
@ -41,11 +41,11 @@ pub fn generate_generate_ci_function(input: &syn::DeriveInput) -> TokenStream2 {
let functions_to_generate: TokenStream2 = functions_to_generate.into_iter().collect(); let functions_to_generate: TokenStream2 = functions_to_generate.into_iter().collect();
let gen = quote! { let gen = quote! {
pub fn generate_ci_functions( pub fn generate_ci_functions(
context: &mut rlua::Context, lua: &mut mlua::Lua,
tx: std::sync::mpsc::Sender<crate::app::events::event_types::Event>) tx: tokio::sync::mpsc::Sender<crate::app::events::event_types::Event>)
{ {
context.set_named_registry_value("sender_for_ci_commands", tx).expect("This should always work, as the value is added before all else"); lua.set_named_registry_value("sender_for_ci_commands", std::sync::Arc::new(std::sync::Mutex::new(tx))).expect("This should always work, as the value is added before all else");
let globals = context.globals(); let globals = lua.globals();
#input_tokens #input_tokens
} }
#functions_to_generate #functions_to_generate
@ -61,7 +61,7 @@ fn generate_ci_part(field: &syn::Field) -> TokenStream2 {
let function_name_ident = format_ident!("fun_{}", field_ident); let function_name_ident = format_ident!("fun_{}", field_ident);
let function_name = format!("{}", field_ident); let function_name = format!("{}", field_ident);
quote! { quote! {
let #function_name_ident = context.create_function(#field_ident).expect( let #function_name_ident = lua.create_async_function(#field_ident).expect(
&format!( &format!(
"The function: `{}` should be defined", "The function: `{}` should be defined",
#function_name #function_name

View File

@ -1,4 +1,5 @@
// FIXME: This file needs documentation with examples of how the proc macros work. // FIXME: This file needs documentation with examples of how the proc macros work.
// for now use `cargo expand app::command_interface` for an overview
use lua_macros::{ci_command, turn_struct_to_ci_commands}; use lua_macros::{ci_command, turn_struct_to_ci_commands};
use rlua::Context; use rlua::Context;
@ -21,7 +22,7 @@ use super::events::event_types::Event;
/// where $return_type is the type returned by the function (the only supported ones are right now /// where $return_type is the type returned by the function (the only supported ones are right now
/// `String` and `()`). /// `String` and `()`).
#[turn_struct_to_ci_commands] #[turn_struct_to_ci_commands]
struct Commands<'lua> { struct Commands {
greet: fn(usize) -> String, greet: fn(usize) -> String,
// Closes the application // Closes the application
@ -42,11 +43,11 @@ struct Commands<'lua> {
} }
#[ci_command] #[ci_command]
fn greet(context: Context, input_str: String) -> Result<String, rlua::Error> { async fn greet(lua: &mlua::Lua, input_str: String) -> Result<String, mlua::Error> {
Ok(format!("Name is {}", input_str)) Ok(format!("Name is {}", input_str))
} }
#[ci_command] #[ci_command]
fn room_message_send(context: Context, input_str: String) -> Result<String, rlua::Error> { async fn room_message_send(lua: &mlua::Lua, input_str: String) -> Result<String, mlua::Error> {
Ok(format!("Sent message: {}", input_str)) Ok(format!("Sent message: {}", input_str))
} }

View File

@ -1,20 +1,22 @@
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use cli_log::info; use cli_log::info;
use crate::app::{App, events::event_types::{EventStatus, Event}}; use crate::app::{
events::event_types::{Event, EventStatus},
App,
};
pub async fn handle(app: &mut App<'_>, command: &str) -> Result<EventStatus> { pub async fn handle(app: &mut App<'_>, command: &str) -> Result<EventStatus> {
info!("Recieved ci command: `{command}`; executing.."); info!("Recieved ci command: `{command}`; executing..");
// TODO: Should the ci support more than strings? // TODO: Should the ci support more than strings?
let output = app.lua.context(|context| -> Result<String> { let output = app
let output = context .lua
.load(&command) .load(command)
.eval::<String>() .eval_async::<String>()
.with_context(|| format!("Failed to execute: `{command}`"))?; .await
info!("Function evaluated to: `{output}`"); .with_context(|| format!("Failed to execute: `{command}`"))?;
Ok(output) info!("Function evaluated to: `{output}`");
})?;
app.transmitter.send(Event::CiOutput(output)); app.transmitter.send(Event::CiOutput(output));

View File

@ -3,13 +3,14 @@ pub mod events;
pub mod status; pub mod status;
pub mod transmitter; pub mod transmitter;
use std::{path::Path, sync::mpsc::Sender as StdSender}; use std::path::Path;
use anyhow::{Context, Error, Result}; use anyhow::{Context, Error, Result};
use cli_log::info; use cli_log::info;
use matrix_sdk::Client; use matrix_sdk::Client;
use rlua::Lua; use mlua::Lua;
use status::{State, Status}; use status::{State, Status};
use tokio::sync::mpsc;
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
use crate::{ use crate::{
@ -34,12 +35,10 @@ pub struct App<'ui> {
impl App<'_> { impl App<'_> {
pub fn new() -> Result<Self> { pub fn new() -> Result<Self> {
fn set_up_lua(tx: StdSender<Event>) -> Lua { fn set_up_lua(tx: mpsc::Sender<Event>) -> Lua {
let lua = Lua::new(); let lua = Lua::new();
lua.context(|mut lua_context| { generate_ci_functions(&mut lua, tx);
generate_ci_functions(&mut lua_context, tx);
});
lua lua
} }
@ -61,7 +60,7 @@ impl App<'_> {
input_listener_killer: CancellationToken::new(), input_listener_killer: CancellationToken::new(),
matrix_listener_killer: CancellationToken::new(), matrix_listener_killer: CancellationToken::new(),
lua: set_up_lua(transmitter.std_tx()), lua: set_up_lua(transmitter.tx()),
}) })
} }

View File

@ -1,5 +1,3 @@
use std::sync::mpsc as StdMpsc;
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use tokio::sync::mpsc; use tokio::sync::mpsc;
@ -8,29 +6,20 @@ use super::events::event_types::Event;
pub struct Transmitter { pub struct Transmitter {
tx: mpsc::Sender<Event>, tx: mpsc::Sender<Event>,
rx: mpsc::Receiver<Event>, rx: mpsc::Receiver<Event>,
std_tx: StdMpsc::Sender<Event>,
std_rx: StdMpsc::Receiver<Event>,
} }
impl Transmitter { impl Transmitter {
pub fn new() -> Transmitter { pub fn new() -> Transmitter {
let (std_tx, std_rx) = StdMpsc::channel();
let (tx, rx) = mpsc::channel(256); let (tx, rx) = mpsc::channel(256);
Transmitter { Transmitter {
tx, tx,
rx, rx,
std_tx,
std_rx,
} }
} }
pub fn tx(&self) -> mpsc::Sender<Event> { pub fn tx(&self) -> mpsc::Sender<Event> {
self.tx.to_owned() self.tx.to_owned()
} }
pub fn std_tx(&self) -> StdMpsc::Sender<Event> {
self.std_tx.to_owned()
}
pub async fn recv(&mut self) -> Result<Event> { pub async fn recv(&mut self) -> Result<Event> {
match self.rx.recv().await { match self.rx.recv().await {
Some(event) => Ok(event), Some(event) => Ok(event),