From 871c9a6d1ed014c93da2436a437df03734e9f76c Mon Sep 17 00:00:00 2001 From: MystiPanda Date: Sun, 10 Dec 2023 19:47:45 +0800 Subject: [PATCH] feat: Support windows aarch64 --- .gitmodules | 3 + src-tauri/Cargo.toml | 2 +- src-tauri/quick-rs | 1 + src-tauri/src/enhance/script.rs | 130 +++++++++++++++++++------------- 4 files changed, 81 insertions(+), 55 deletions(-) create mode 100644 .gitmodules create mode 160000 src-tauri/quick-rs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2eda7e4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src-tauri/quick-rs"] + path = src-tauri/quick-rs + url = https://github.com/clash-verge-rev/quick-rs.git diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 2f1a3be..d67f6ed 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -25,7 +25,6 @@ log4rs = "1" nanoid = "0.4" chrono = "0.4" sysinfo = "0.30" -rquickjs = "0.3" # 高版本不支持 Linux aarch64 serde_json = "1.0" serde_yaml = "0.9" once_cell = "1.18" @@ -33,6 +32,7 @@ port_scanner = "0.1.5" delay_timer = "0.11.5" parking_lot = "0.12" percent-encoding = "2.3.1" +quick-rs = { path = "quick-rs" } window-shadows = { version = "0.2" } tokio = { version = "1", features = ["full"] } serde = { version = "1.0", features = ["derive"] } diff --git a/src-tauri/quick-rs b/src-tauri/quick-rs new file mode 160000 index 0000000..78277c4 --- /dev/null +++ b/src-tauri/quick-rs @@ -0,0 +1 @@ +Subproject commit 78277c4509c64f18c0fc5c9f2b84671de7c83343 diff --git a/src-tauri/src/enhance/script.rs b/src-tauri/src/enhance/script.rs index 30a922f..d47dc33 100644 --- a/src-tauri/src/enhance/script.rs +++ b/src-tauri/src/enhance/script.rs @@ -3,61 +3,83 @@ use anyhow::Result; use serde_yaml::Mapping; pub fn use_script(script: String, config: Mapping) -> Result<(Mapping, Vec<(String, String)>)> { - use rquickjs::{function::Func, Context, Runtime}; - use std::sync::{Arc, Mutex}; - - let runtime = Runtime::new().unwrap(); - let context = Context::full(&runtime).unwrap(); - let outputs = Arc::new(Mutex::new(vec![])); - - let copy_outputs = outputs.clone(); - let result = context.with(|ctx| -> Result { - ctx.globals().set( - "__verge_log__", - Func::from(move |level: String, data: String| { - let mut out = copy_outputs.lock().unwrap(); - out.push((level, data)); - }), - )?; - - ctx.eval( - r#"var console = Object.freeze({ - log(data){__verge_log__("log",JSON.stringify(data))}, - info(data){__verge_log__("info",JSON.stringify(data))}, - error(data){__verge_log__("error",JSON.stringify(data))}, - debug(data){__verge_log__("debug",JSON.stringify(data))}, - });"#, - )?; - - let config = use_lowercase(config.clone()); - let config_str = serde_json::to_string(&config)?; - - let code = format!( - r#"try{{ + use quick_rs::{context::Context, function::Function, module::Module, runtime::Runtime}; + + let config = use_lowercase(config.clone()); + let config_str = serde_json::to_string(&config)?; + + let runtime = Runtime::new(); + let context = Context::from(&runtime); + + let code = format!( + r#" + let output = []; + + function __verge_log__(type, data) {{ + output.push([type, data]); + }} + + var console = Object.freeze({{ + log(data) {{ __verge_log__("log", JSON.stringify(data)) }}, + info(data) {{ __verge_log__("info", JSON.stringify(data)) }}, + error(data) {{ __verge_log__("error", JSON.stringify(data)) }}, + debug(data) {{ __verge_log__("debug", JSON.stringify(data)) }}, + }}); + {script}; - JSON.stringify(main({config_str})||'') - }} catch(err) {{ - `__error_flag__ ${{err.toString()}}` - }}"# - ); - let result: String = ctx.eval(code.as_str())?; - if result.starts_with("__error_flag__") { - anyhow::bail!(result[15..].to_owned()); - } - if result == "\"\"" { - anyhow::bail!("main function should return object"); - } - Ok(serde_json::from_str::(result.as_str())?) - }); - - let mut out = outputs.lock().unwrap(); - match result { - Ok(config) => Ok((use_lowercase(config), out.to_vec())), - Err(err) => { - out.push(("exception".into(), err.to_string())); - Ok((config, out.to_vec())) - } - } + + export function _main(){{ + try{{ + let result = JSON.stringify(main({config_str})||""); + return JSON.stringify({{result, output}}); + }} catch(err) {{ + output.push(["exception", err.toString()]); + return JSON.stringify({{result: "__error__", output}}); + }} + }} + "# + ); + let value = context.eval_module(&code, "_main")?; + let module = Module::new(value)?; + let value = module.get("_main")?; + let function = Function::new(value)?; + let value = function.call(vec![])?; + let result = serde_json::from_str::(&value.to_string()?)?; + result + .as_object() + .map(|obj| { + let result = obj.get("result").unwrap().as_str().unwrap(); + let output = obj.get("output").unwrap(); + + let mut out = output + .as_array() + .unwrap() + .iter() + .map(|item| { + let item = item.as_array().unwrap(); + ( + item[0].as_str().unwrap().into(), + item[1].as_str().unwrap().into(), + ) + }) + .collect::>(); + if result.is_empty() { + anyhow::bail!("main function should return object"); + } + if result == "__error__" { + return Ok((config, out.to_vec())); + } + let result = serde_json::from_str::(result); + + match result { + Ok(config) => Ok((use_lowercase(config), out.to_vec())), + Err(err) => { + out.push(("exception".into(), err.to_string())); + Ok((config, out.to_vec())) + } + } + }) + .unwrap_or_else(|| anyhow::bail!("Unknown result")) } #[test] -- 2.43.0.windows.1