diff --git a/Cargo.lock b/Cargo.lock index f4dc5ba6c..75c5a10ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -772,6 +772,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + [[package]] name = "encode_unicode" version = "0.3.6" @@ -1391,6 +1397,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.3" @@ -1608,12 +1623,28 @@ dependencies = [ "futures-util", "lua-src", "luajit-src", + "mlua_derive", "num-traits", "once_cell", "pkg-config", "rustc-hash", ] +[[package]] +name = "mlua_derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9214e60d3cf1643013b107330fcd374ccec1e4ba1eef76e7e5da5e8202e71c0" +dependencies = [ + "itertools", + "once_cell", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn", +] + [[package]] name = "native-tls" version = "0.2.10" diff --git a/Cargo.toml b/Cargo.toml index 6d707cfab..a76c3eb16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ proc-macro2 = { version = "1.0", features = ["span-locations"] } lazy_static = "1.4.0" # plugin packages -mlua = { version = "0.8.1", features = ["lua54", "vendored", "async", "send"] } +mlua = { version = "0.8.1", features = ["lua54", "vendored", "async", "send", "macros"] } ctrlc = "3.2.3" [[bin]] diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index 9c99c8266..2e02b8946 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -4,7 +4,7 @@ use std::{ sync::Mutex, }; -use mlua::{AsChunk, Lua, Table}; +use mlua::{AsChunk, chunk, Lua, Table}; use serde::{Deserialize, Serialize}; use serde_json::json; @@ -44,7 +44,7 @@ impl PluginManager { // // if plugin system is available, just set manager to nil. // lua.globals().set("manager", mlua::Value::Nil).unwrap(); return Ok(()); - } + } let manager = lua.create_table().unwrap(); let plugin_dir = Self::init_plugin_dir(); @@ -108,19 +108,39 @@ impl PluginManager { lua.globals().set("manager", manager).unwrap(); for (idx, path, info) in init_list { - let res = lua.load(&format!("manager[{idx}].on_init()")).exec(); - if res.is_ok() { - let mut file = std::fs::File::create(path).unwrap(); - let value = json!({ - "name": info.name, - "author": info.author, - "repository": info.repository, - "version": info.version, - "generate_time": chrono::Local::now().timestamp(), - }); - let buffer = serde_json::to_string_pretty(&value).unwrap(); - let buffer = buffer.as_bytes(); - file.write_all(buffer).unwrap(); + let res = lua + .load(mlua::chunk! { + manager[$idx].on_init() + }) + .eval::(); + match res { + Ok(true) => { + // plugin init success, create `dcp.json` file. + let mut file = std::fs::File::create(path).unwrap(); + let value = json!({ + "name": info.name, + "author": info.author, + "repository": info.repository, + "version": info.version, + "generate_time": chrono::Local::now().timestamp(), + }); + let buffer = serde_json::to_string_pretty(&value).unwrap(); + let buffer = buffer.as_bytes(); + file.write_all(buffer).unwrap(); + } + Ok(false) => { + log::warn!("Plugin init function result is `false`, init failed."); + let _ = lua.load(mlua::chunk! { + table.remove(manager, $idx) + }).exec(); + } + Err(e) => { + // plugin init failed + let _ = lua.load(mlua::chunk! { + table.remove(manager, $idx) + }).exec(); + log::warn!("Plugin init failed: {e}"); + } } } return Ok(()); @@ -269,4 +289,8 @@ impl PluginManager { res } + + pub fn plugin_status() { + let lua = LUA.lock().unwrap(); + } }