Skip to main content

xyz_rust/
config.rs

1// 派发配置:模式词、能力开关与内置参数。零值即默认可直接使用;
2// 命令行 --xyz.* 与各模式的裸名 flag 优先级高于这里的字段值。
3
4use std::time::Duration;
5
6use crate::logx;
7
8/// ModeWords 重命名内建模式关键词。留空的字段保持默认(serve、mcp、
9/// help)。
10#[derive(Debug, Clone, Default)]
11pub struct ModeWords {
12    pub serve: String,
13    /// 独立的 HTTP 模式(仅 REST + /openapi.json,不挂 /mcp;spec §13.1)。
14    pub http: String,
15    pub mcp: String,
16    pub help: String,
17}
18
19/// Capabilities 在运行时开关通道(与 build feature 相互独立)。零值保持
20/// 全部可用。禁用通道只移除它自己的运行时路径:模式词(serve/mcp/help)
21/// 与 -v/--version 继续工作,被禁用的模式以清晰错误应答。被禁通道的
22/// CLI()/HTTP()/MCP() 配置照常编译与运行——只是不再被消费。
23#[derive(Debug, Clone, Copy, Default)]
24pub struct Capabilities {
25    /// 不在命令注册表上生成子命令(mcp/serve/help/-v 仍可用)。
26    pub no_cli: bool,
27    /// mcp 模式不可用(stdio/http 都拒绝)。
28    pub no_mcp: bool,
29    /// serve 模式不可用。
30    pub no_http: bool,
31}
32
33/// Config 调整派发器。零值保持全部默认。
34#[derive(Debug, Clone, Default)]
35pub struct Config {
36    pub modes: ModeWords,
37    pub capabilities: Capabilities,
38
39    /// serve 与 mcp(http) 模式的默认监听地址(各模式自己的 --addr flag
40    /// 优先)。
41    pub addr: String,
42    /// 开启 serve REST 与 MCP http 传输的 Bearer 凭据校验,每个元素是
43    /// 一个可接受的 token;空表示不校验。命令行写法:--xyz.bearer=tok1,tok2
44    /// (stdio 传输为本地进程,不受影响)。
45    pub bearer_tokens: Vec<String>,
46
47    /// 库自身诊断的日志级别(logx 输出到 stderr)。零值(LevelUnset)
48    /// 保持默认 Info。命令行:--xyz.log-level=debug|info|warn|error。
49    pub log_level: crate::logx::Level,
50    /// serve 模式的每请求超时(TimeoutLayer);0 = 不设超时。
51    /// (标准头超时在 Rust 实现里未单独配置,见 README 与 Go 版差异节。)
52    pub timeout: Duration,
53    /// cert_file/key_file 同时给定则 serve 以 TLS 监听
54    /// (--xyz.tls-cert/--xyz.tls-key)。
55    pub cert_file: String,
56    pub key_file: String,
57    /// CORSOrigins 非空则开启 CORS:逐个 Origin 放行("*" 表示任意来源),
58    /// OPTIONS 预检在鉴权之前应答。命令行:--xyz.cors=origin1,origin2。
59    pub cors_origins: Vec<String>,
60
61    /// 界面语言覆盖:""=自动(--xyz.lang flag > 本字段 > LANG/LC_ALL 环境
62    /// 检测 > 英文默认)。取值 "en" | "zh-CN"。
63    pub lang: String,
64    /// 用户的多语言内容覆盖表:语言 → (消息键 → 文本)。键名见 lang 目录
65    /// (xyz-spec §15.8 的规范键表)。
66    pub translations: std::collections::HashMap<String, std::collections::HashMap<String, String>>,
67
68    /// serve/mcp 启动时注入的通道级默认参数(字段线上名 → 字符串值):
69    /// 请求/调用未显式提供时自动补上,优先级高于全局 default 属性、低于
70    /// 显式入参与接口默认。命令行:--default k=v(可重复/逗号分隔对)。
71    pub channel_defaults: std::collections::HashMap<String, String>,
72
73    /// help 总览的自定义文本块:前者原样插在总览开头(程序名/描述/版本/
74    /// 仓库地址等自己拼),后者插在结尾(命令表之后,即使命令表被隐藏也
75    /// 打印)。空 = 不插入。
76    pub help_before: String,
77    pub help_after: String,
78
79    /// 应用名(spec §11.6/§12.6):X-App-Name 响应头与 MCP serverInfo.name。
80    /// 空 = 二进制 basename。
81    pub name: String,
82    /// 应用版本(spec §11.6/§12.6):X-App-Version 响应头与
83    /// serverInfo.version。空 = version::version()(默认 "dev")。
84    /// 与 xyz 库自身的版本(version::SDK_VERSION → X-XYZ-Version)无关。
85    pub version: String,
86    /// 代码级全局默认格式(spec §10.7 第四层):""|auto = 按 TTY 解析为
87    /// format_interactive / format_piped。命令行 --xyz.format(第二层,
88    /// format_from_flag 置位)与逐命令 CliHints.format(第三层)优先。
89    pub format: String,
90    /// format=auto 时交互式终端下的具体格式(默认 text)。
91    pub format_interactive: String,
92    /// format=auto 时非交互(管道/重定向/其他程序调用)下的具体格式
93    /// (默认 jsonl)。
94    pub format_piped: String,
95    /// 标记 format 来自命令行 --xyz.format(命令行层,高于逐命令 hint)。
96    pub format_from_flag: bool,
97    /// 附加到每个 HTTP 响应的自定义静态头(键值原样写入;与自动
98    /// X-App-*/X-XYZ-* 头并存)。命令行:--xyz.header k=v(可重复)。
99    pub response_headers: Vec<(String, String)>,
100    /// 关闭自动服务器上下文头(HTTP 的 X-App-*/X-XYZ-* 与 MCP 结果的
101    /// _meta.xyz):spec §11.6/§12.8 的单一开关。自定义头不受影响。
102    /// 命令行:--xyz.no-server-headers。
103    pub no_server_headers: bool,
104    /// 接受未知 query 参数(默认 false = 严格:400 `invalid_input`,消息列出
105    /// 该路由允许的参数集;spec §11.2)。静默忽略会让拼错/已移除的参数看起来
106    /// 生效。命令行:--xyz.allow-unknown-query。
107    pub allow_unknown_query: bool,
108}
109
110impl Config {
111    pub fn default_log_level(&self) -> logx::Level {
112        self.log_level
113    }
114
115    /// 应用名:config 覆盖 > 二进制 basename(spec §11.6/§12.6)。
116    pub fn resolved_name(&self) -> String {
117        if !self.name.is_empty() {
118            return self.name.clone();
119        }
120        crate::cli::bin_name()
121    }
122
123    /// 应用版本:config 覆盖 > 版本槽(默认 "dev")。
124    pub fn resolved_version(&self) -> String {
125        if !self.version.is_empty() {
126            return self.version.clone();
127        }
128        crate::version::version().to_string()
129    }
130}