xyz_rust/lib.rs
1//! # xyz-rust — One definition, three interfaces
2//!
3//! 一次定义(入参 struct + 校验 + 每渠道细节),一个二进制自动讲三种接口:
4//! **CLI 子命令**、**HTTP REST 服务**(带 OpenAPI 文档)与 **MCP 工具服务器**
5//! (官方 Rust SDK `rmcp`)。运行模式由库自行判断。
6//!
7//! ```no_run
8//! use xyz_rust::{define, CliHints, HTTPHints, XyzArgs};
9//! use xyz_rust::errs;
10//!
11//! #[derive(XyzArgs)]
12//! struct AddArgs {
13//! #[xyz(desc = "用户名", required, cli = "positional", http = "path")]
14//! name: String,
15//! #[xyz(desc = "年龄", default = "18")]
16//! age: i32,
17//! }
18//!
19//! fn add(_ctx: &xyz_rust::Ctx, in_: &AddArgs) -> errs::Result<String> {
20//! Ok(format!("{} is {}", in_.name, in_.age))
21//! }
22//!
23//! fn main() {
24//! define::<AddArgs, String, _, _>("user.add", add)
25//! .summary("添加用户")
26//! .cli(CliHints { usage: "add <name>".into(), ..Default::default() })
27//! .http(HTTPHints { method: "POST".into(), path: "/users/{name}".into(), ..Default::default() })
28//! .run(); // 注册 + 派发 + exit — 整个程序就这一条链
29//! }
30//! ```
31//!
32//! 进程级默认注册表背后的派生器:`Main` 派发默认注册表并内部调用
33//! `std::process::exit`,因此 main 里写的清理代码不会在它们之后执行。需要
34//! defer 清理、自定义退出码、多个注册表或嵌入派发器时,用显式注册表的
35//! `run` / `run_config` 版本,它们只返回退出码。
36//!
37//! 没有任何注册命令的注册表是静默 no-op:派发器直接退出 0,什么都不打印。
38//!
39//! 模式探测:
40//!
41//! ```text
42//! <app> [命令] ... -> CLI 前端(子命令、flag、位置参数、-h / -v)
43//! <app> mcp stdio|http -> MCP 前端(官方 SDK;--versions 钉定协议版本;sse 随
44//! 2026-07-28 修订从官方 Rust SDK 移除,报错退出)
45//! <app> serve [--addr ...] -> HTTP 前端(REST + /openapi.json + /mcp)
46//! <app> (无参数)| help -> 总览(列出三种形态与命令表)
47//! ```
48//!
49//! 模式关键词默认为 serve / mcp / help 且是保留的顶层名字;两者都可经
50//! `Config.modes` 重命名。派发在 [`dispatch`] 模块,配置类型在
51//! [`config`],内置参数解析在 [`builtins`],总览渲染在 [`overview`],流式
52//! 构建器在 [`builder`]。
53
54// 自别名:宏生成的 ::xyz_rust:: 绝对路径在库自身测试里同样可达。
55extern crate self as xyz_rust;
56
57#[cfg(test)]
58mod dispatch_test;
59
60pub mod blocks;
61pub mod builder;
62pub mod builtins;
63pub mod cli;
64pub mod config;
65pub mod ctx;
66pub mod dispatch;
67pub mod errors;
68pub mod lang;
69pub mod logx;
70// httpapi 在 http 或 mcp 任一通道存在时都在树中(Go 的结构同款:mcp 复用
71// http 中间件积木;两个通道都裁掉时整体消失)。
72#[cfg(any(feature = "http", feature = "mcp"))]
73pub mod httpapi;
74#[cfg(feature = "mcp")]
75pub mod mcp;
76pub mod overview;
77pub mod registry;
78pub mod spec;
79pub mod termx;
80pub mod version;
81
82pub use ctx::Ctx;
83
84/// 当前界面语言(spec §14 item7):进程级语言槽(`--xyz.lang` > Config >
85/// 环境检测 > en,§15.5)。
86pub fn language() -> &'static str {
87 crate::lang::current().as_str()
88}
89
90/// 进程主输出是否交互式(TTY)。这是格式轴(§10.7)与保留的样式轴
91/// (§10.7a)共享的同一探针接缝。
92pub fn interactive() -> bool {
93 crate::termx::interactive()
94}
95
96/// 颜色是否被环境抑制(`NO_COLOR` 非空或 `TERM=dumb`;§10.7a 保留样式轴
97/// 的输入,先以访问器形式暴露)。
98pub fn no_color() -> bool {
99 crate::termx::no_color()
100}
101
102/// 环境上下文快照(现象 §14 item7 的 `Env()` 访问器)。
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct EnvContext {
105 pub language: &'static str,
106 pub interactive: bool,
107 pub no_color: bool,
108}
109
110/// 一次取齐语言/交互式/颜色抑制(spec §14 item7)。
111pub fn env() -> EnvContext {
112 EnvContext {
113 language: language(),
114 interactive: interactive(),
115 no_color: no_color(),
116 }
117}
118
119/// 请求上下文携带的界面语言(spec §11.7);未绑定时回退进程语言
120/// (Go `xyz.LanguageFromCtx(ctx)` 的对应物)。
121pub fn language_from_ctx(ctx: &Ctx) -> String {
122 ctx.language()
123 .map(|s| s.to_string())
124 .unwrap_or_else(|| crate::lang::current().as_str().to_string())
125}
126pub use errors as errs;
127
128// 派生宏在最上层以惯用名导出(xyz_rust::XyzArgs 直接可用作 #[derive])。
129pub use xyz_rust_macros::{XyzArgs, XyzField, XyzOutput};
130
131// 宏生成代码用的绝对路径词汇表(用户 crate 只依赖 xyz-rust)。
132pub use chrono;
133pub use serde;
134pub use serde_json;
135
136pub use builder::{Builder, Definable, define};
137pub use config::{Capabilities, Config, ModeWords};
138pub use dispatch::{main as main_entry, main_config, run, run_config};
139pub use errors::{Error, Kind};
140pub use lang::{XyzLang, set as set_lang, t, tf};
141pub use registry::Registry;
142pub use spec::{
143 CliFieldHint, CliHints, Entry, FieldMeta, HTTPFieldHint, HTTPHints, MCPFieldHint, MCPHints,
144 Schema, XyzArgs, XyzField,
145};
146pub use version::{set_version, version};