Files
mirror/src/config.rs
CNWei ed5439eaa1 refactor: 拆分代码结构为 lib.rs 与多模块架构
- 将核心业务逻辑抽离至 lib.rs,精简 main.rs 为纯粹的 CLI 入口
- 将代码按职责拆分为 config、env、runtime、shim 等子模块
- 提高可测试性与代码复用度
2026-08-14 10:36:09 +08:00

92 lines
3.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()),
}),
}
}
}