Get Runtime working...

Isaac Clayton created

Change summary

crates/runner/Cargo.toml     |  4 +++-
crates/runner/src/lib.rs     | 17 +++++++++++++++--
crates/runner/src/main.rs    | 22 +++++++++++++++-------
crates/runner/src/runtime.rs | 20 ++++++++++++++++----
4 files changed, 49 insertions(+), 14 deletions(-)

Detailed changes

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"

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::<String, Value>() {
             if let Ok((k, _)) = pair {
@@ -24,4 +25,16 @@ impl Runtime for Lua {
 
         globals
     }
+
+    fn val<T: DeserializeOwned>(&self, name: String) -> Option<T> {
+        let val: Value = self.globals().get(name).ok()?;
+        Some(self.from_value(val).ok()?)
+    }
+
+    fn call<T: Serialize + DeserializeOwned>(&self, name: String, arg: T) -> Option<T> {
+        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()?)
+    }
 }

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::<TestRunner>().unwrap();
+    println!("{:#?}", runner);
 }
 
-struct InterfaceX;
+#[derive(Debug)]
+struct TestRunner {
+    query: String,
+}
 
-impl InterfaceX {
-    pub fn get_x<T: Runtime>(runtime: T) -> usize {
-        // runtime.get("x")
-        todo!()
+impl Interface for TestRunner {
+    fn from_runtime<T: Runtime>(runtime: &T) -> Option<TestRunner> {
+        let query: String = runtime.val("query".to_string())?;
+        Some(TestRunner { query })
     }
 }

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<String>;
+pub type Handles = HashSet<String>;
+
+pub trait Interface
+where
+    Self: Sized,
+{
+    fn from_runtime<T: Runtime>(runtime: &T) -> Option<Self>;
+}
 
 pub trait Runtime
 where
@@ -11,7 +19,11 @@ where
     type Module;
 
     fn init(plugin: Self::Module) -> Option<Self>;
-    fn interface(&self) -> Interface;
-    // fn val<'a, T>(&'a self, name: String) -> Option<T>;
-    // fn call<'a, A: MyFromLua<'a>, R>(&'a mut self, name: String, arg: A) -> Option<R>;
+    fn handles(&self) -> Handles;
+    fn val<T: DeserializeOwned>(&self, name: String) -> Option<T>;
+    fn call<T: Serialize + DeserializeOwned>(&self, name: String, arg: T) -> Option<T>;
+
+    fn as_interface<T: Interface>(&self) -> Option<T> {
+        Interface::from_runtime(self)
+    }
 }