floss-cli 0.1.2

在 Rust 中以子进程方式调用 FLARE FLOSS CLI,并可选解析 -j JSON 输出
Documentation
# floss-cli

一个极薄的 Rust 库:通过启动外部进程的方式调用 `floss`(FLARE Obfuscated String Solver)命令行工具。

核心目标:**不重写 FLOSS 的分析逻辑**,只负责:
- 组装参数(支持透传任意 FLOSS CLI 参数,覆盖 `floss -h/-H` 的全部功能)
- 执行命令并捕获 `stdout/stderr`
- 可选:在启用 `-j/--json` 时解析 JSON 输出(内置 `ResultDocument`,也支持自定义 `serde` 类型)

## 完整用法文档

全部 API、执行模式、错误语义与示例见 [USAGE.md](USAGE.md)。

## 快速使用

> 本库基于 tokio 异步运行时,调用时需处于 tokio runtime 中。

```rust
use floss_cli::{FlossCli, Result, ResultDocument};

#[tokio::main]
async fn main() -> Result<()> {
    // 方式 0(推荐):自动探测
    // - 优先使用 PATH 里的 floss/floss.exe
    // - 否则回退到可用的 python -m floss
    let cli = FlossCli::detect().await?;

    // 方式 1:假设系统 PATH 里有 floss/floss.exe
    // let cli = FlossCli::new("floss");

    // 方式 2:用 python -m floss(适合只安装了 Python 包的场景)
    // let cli = FlossCli::python_module("python");

    let doc: ResultDocument = cli
        .command()
        .arg("--only")
        .args(["static", "decoded"])
        .sample("malware.exe")
        .run_results()
        .await?;

    println!("decoded strings: {}", doc.strings.decoded_strings.len());
    Ok(())
}
```

## 执行模式(全量异步)

- `run_raw().await`:捕获 stdout/stderr,不检查退出码
- `run_allow_exit_codes([1, 2]).await`:允许指定退出码视为成功
- `run_inherit().await`:stdout/stderr 直连终端,不检查退出码
- `run_inherit_checked().await`:直连终端,退出码非 0 直接返回错误
- `spawn()`:直连终端,返回 `tokio::process::Child`
- `spawn_piped()`:stdout/stderr 为 piped,返回 `tokio::process::Child` 供流式读取
- `command_line()`:返回 `program + args`(含 `--` 与 sample),便于日志/审计

> `spawn/spawn_piped` 不自动绑定 Job Object,也不处理超时;需要调用方自行管理。

## 输出控制

- `run_raw_limited(max_bytes).await`:限制 stdout/stderr 的最大捕获字节数,超出部分会被丢弃

## 环境变量覆盖(优先级从高到低)

1) `FLOSS_EXE`:直接指定可执行文件路径  
2) `FLOSS_PYTHON` + `FLOSS_PYTHON_ARGS`:用指定 Python 解释器运行 `-m floss`  
3) `PATH` 中的 `floss/floss.exe`  
4) 默认 Python 候选(Windows: `python/python3/py -3`;其他系统: `python3/python`)

> `FLOSS_PYTHON_ARGS` 使用空白分隔,支持用 `'``"` 包裹含空格的参数;在 `"` 中支持 `\"` 转义双引号(其余转义不支持)。

## 超时说明

- 超时会尝试终止进程树:Windows 优先使用 Job Object(`KILL_ON_JOB_CLOSE`),失败回退 `taskkill /T /F`/`kill`;Unix 先发 `SIGTERM`(100ms 宽限),再升级到 `SIGKILL`- 若无法终止进程,会返回 `FlossError::TimedOutKillFailed`,并尽量避免主线程卡死。

## 读取 FLOSS 帮助(覆盖全部 CLI 功能)

```rust
use floss_cli::{FlossCli, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let cli = FlossCli::new("floss");
    println!("{}", cli.help().await?);      // 等价于 floss -h
    println!("{}", cli.help_all().await?);  // 等价于 floss -H(高级参数)
    Ok(())
}
```

## 设计约束

- 本库不依赖 FLOSS 的 Python 源码 API;只依赖“可执行的 floss CLI”(或 `python -m floss`)。
- 若你希望“调用 FLOSS 的所有功能”,请直接透传参数:`.arg(...)` / `.args(...)`