diff --git a/crates/runner/Cargo.toml b/crates/runner/Cargo.toml index fe49be4bc9..eae03bca0c 100644 --- a/crates/runner/Cargo.toml +++ b/crates/runner/Cargo.toml @@ -4,4 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -mlua = { version = "0.8.0-beta.5", features = ["lua54", "vendored"] } +mlua = { version = "0.8.0-beta.5", features = ["lua54", "vendored", "serialize"] } +serde = "1.0" +# bincode = "1.3" diff --git a/crates/runner/src/lib.rs b/crates/runner/src/lib.rs index d305f092d5..82aaa62368 100644 --- a/crates/runner/src/lib.rs +++ b/crates/runner/src/lib.rs @@ -1,9 +1,10 @@ use std::collections::{HashMap, HashSet}; -use mlua::{Error, FromLua, Function, Lua, ToLua, UserData, Value}; +use mlua::{Error, FromLua, Function, Lua, LuaSerdeExt, ToLua, UserData, Value}; pub mod runtime; pub use runtime::*; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; impl Runtime for Lua { type Module = String; @@ -14,7 +15,7 @@ impl Runtime for Lua { return Some(lua); } - fn interface(&self) -> Interface { + fn handles(&self) -> Handles { let mut globals = HashSet::new(); for pair in self.globals().pairs::() { if let Ok((k, _)) = pair { @@ -24,4 +25,16 @@ impl Runtime for Lua { globals } + + fn val(&self, name: String) -> Option { + let val: Value = self.globals().get(name).ok()?; + Some(self.from_value(val).ok()?) + } + + fn call(&self, name: String, arg: T) -> Option { + let fun: Function = self.globals().get(name).ok()?; + let arg: Value = self.to_value(&arg).ok()?; + let result = fun.call(arg).ok()?; + Some(self.from_value(result).ok()?) + } } diff --git a/crates/runner/src/main.rs b/crates/runner/src/main.rs index c82e245619..48cdfb07b6 100644 --- a/crates/runner/src/main.rs +++ b/crates/runner/src/main.rs @@ -3,15 +3,23 @@ use mlua::{Lua, Result}; use runner::*; pub fn main() { - let lua: Lua = Runtime::init("x = 7".to_string()).unwrap(); - println!("{:?}", lua.interface()); + let lua: Lua = Runtime::init( + "query = \"Some random tree-sitter query\"\nprint(\"Hello from the Lua test runner!\")" + .to_string(), + ) + .unwrap(); + let runner: TestRunner = lua.as_interface::().unwrap(); + println!("{:#?}", runner); } -struct InterfaceX; +#[derive(Debug)] +struct TestRunner { + query: String, +} -impl InterfaceX { - pub fn get_x(runtime: T) -> usize { - // runtime.get("x") - todo!() +impl Interface for TestRunner { + fn from_runtime(runtime: &T) -> Option { + let query: String = runtime.val("query".to_string())?; + Some(TestRunner { query }) } } diff --git a/crates/runner/src/runtime.rs b/crates/runner/src/runtime.rs index 8436e29da7..da4fd0de30 100644 --- a/crates/runner/src/runtime.rs +++ b/crates/runner/src/runtime.rs @@ -1,8 +1,16 @@ use std::collections::HashSet; use mlua::{FromLua, Lua, ToLua, Value}; +use serde::{de::DeserializeOwned, Serialize}; -pub type Interface = HashSet; +pub type Handles = HashSet; + +pub trait Interface +where + Self: Sized, +{ + fn from_runtime(runtime: &T) -> Option; +} pub trait Runtime where @@ -11,7 +19,11 @@ where type Module; fn init(plugin: Self::Module) -> Option; - fn interface(&self) -> Interface; - // fn val<'a, T>(&'a self, name: String) -> Option; - // fn call<'a, A: MyFromLua<'a>, R>(&'a mut self, name: String, arg: A) -> Option; + fn handles(&self) -> Handles; + fn val(&self, name: String) -> Option; + fn call(&self, name: String, arg: T) -> Option; + + fn as_interface(&self) -> Option { + Interface::from_runtime(self) + } }