refactor: 拆分代码结构为 lib.rs 与多模块架构
- 将核心业务逻辑抽离至 lib.rs,精简 main.rs 为纯粹的 CLI 入口 - 将代码按职责拆分为 config、env、runtime、shim 等子模块 - 提高可测试性与代码复用度
This commit is contained in:
92
src/config.rs
Normal file
92
src/config.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use mlua::{FromLua, Lua, Table, Value};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShimConfig {
|
||||
pub target_path: PathBuf,
|
||||
pub args: Option<Vec<String>>,
|
||||
pub envs: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
impl ShimConfig {
|
||||
/// 根据配置快速构建准备执行的 Command 对象
|
||||
pub fn to_command(&self) -> Command {
|
||||
let mut cmd = Command::new(&self.target_path);
|
||||
|
||||
if let Some(args) = &self.args {
|
||||
cmd.args(args);
|
||||
}
|
||||
|
||||
if let Some(envs) = &self.envs {
|
||||
for (key, val) in envs {
|
||||
// 直接应用环境变量(Lua 端已经处理好字符串拼接或列表合并)
|
||||
cmd.env(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
cmd
|
||||
}
|
||||
}
|
||||
|
||||
/// 实现 FromLua Trait,由 mlua 自动处理 Table 转换
|
||||
impl FromLua for ShimConfig {
|
||||
fn from_lua(value: Value, _lua: &Lua) -> mlua::Result<Self> {
|
||||
match value {
|
||||
Value::Table(table) => {
|
||||
let path_str: String = table.get("path")?;
|
||||
let args: Option<Vec<String>> = table.get("args")?;
|
||||
// 解析 env Table
|
||||
let mut envs_map = HashMap::new();
|
||||
if let Ok(env_table) = table.get::<Table>("env") {
|
||||
// 获取当前系统的路径分隔符(Windows 为 ";",Unix 为 ":")
|
||||
#[cfg(windows)]
|
||||
let sep = ";";
|
||||
#[cfg(not(windows))]
|
||||
let sep = ":";
|
||||
|
||||
for pair in env_table.pairs::<String, Value>() {
|
||||
let (k, v) = pair?;
|
||||
match v {
|
||||
// 情况 1: 普通字符串,如 HOME = "C:/path" -> 直接覆盖
|
||||
Value::String(s) => {
|
||||
envs_map.insert(k, s.to_str()?.to_string());
|
||||
}
|
||||
// 情况 2: 数组 Table,如 PATH = { bin_dir, get_env("PATH") }
|
||||
Value::Table(arr) => {
|
||||
let paths: Vec<String> = arr
|
||||
// 将 arr 作为序列(数组)处理,每个元素转为 String
|
||||
.sequence_values::<String>()
|
||||
.filter_map(|r| r.ok())
|
||||
.filter(|s| !s.is_empty()) // 过滤空串,防止生成不必要的连续 ;;
|
||||
.collect();
|
||||
|
||||
let combined = paths.join(sep);
|
||||
envs_map.insert(k, combined);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let envs = if envs_map.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(envs_map)
|
||||
};
|
||||
|
||||
Ok(ShimConfig {
|
||||
target_path: PathBuf::from(path_str),
|
||||
args,
|
||||
envs,
|
||||
})
|
||||
}
|
||||
_ => Err(mlua::Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "ShimConfig".into(),
|
||||
message: Some("Expected a Lua table".to_string()),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user