Skip to main content

futucli/
cli.rs

1//! CLI 根参数定义 + 分发入口
2//!
3//! 这里把 `Command` 和 `dispatch` 作为子模块复用,既给 `main.rs` 的主入口用,
4//! 也给 REPL(`cmd::repl`)复用:REPL 把用户输入的一行解析为 `Cli`,
5//! 再调用 `dispatch` 走同一套 handler。
6
7use clap::Parser;
8
9use crate::output::OutputFormat;
10
11/// FutuOpenD-rs 命令行客户端
12#[derive(Parser)]
13#[command(
14    name = "futucli",
15    version,
16    about = "FutuOpenD-rs command-line client",
17    long_about = "连接到 futu-opend 网关,查询行情 / 订阅推送 / 交易。"
18)]
19pub struct Cli {
20    /// 网关地址(可用 FUTU_GATEWAY 环境变量覆盖)
21    #[arg(
22        short,
23        long,
24        global = true,
25        env = "FUTU_GATEWAY",
26        default_value = "127.0.0.1:11111"
27    )]
28    pub gateway: String,
29
30    /// 输出格式
31    #[arg(short, long, global = true, value_enum, default_value_t = OutputFormat::Table)]
32    pub output: OutputFormat,
33
34    /// 启用调试日志
35    #[arg(short, long, global = true)]
36    pub verbose: bool,
37
38    /// 审计日志输出:JSONL 文件路径或目录(v1.2)
39    ///
40    /// 把 futucli 触发的 auth / 交易事件(target = `futu_audit`)单独写到这个
41    /// 文件 / 目录,方便 `jq` / DuckDB 后处理。和 futu-opend / futu-mcp 行为
42    /// 一致:
43    /// - 带扩展名的路径 → 单文件 append
44    /// - 不带扩展名 / 以 `/` 结尾 → 每日滚动 `futu-audit.log`
45    ///
46    /// 注意:审计事件由 futucli 调用的 RPC 客户端逻辑产生(如 `futucli unlock-trade`
47    /// 走 trade:real scope,会被服务端记下来);本 flag 让 *客户端进程自己也*
48    /// 把这些事件落盘到本地,跟服务端审计互为校对。
49    #[arg(long, global = true)]
50    pub audit_log: Option<std::path::PathBuf>,
51
52    #[command(subcommand)]
53    pub command: Command,
54}
55
56mod commands;
57pub use commands::Command;
58
59#[cfg(test)]
60mod tests;
61
62mod dispatch;
63pub use dispatch::dispatch;