name: rust-cli-agent-style description: 从 OpenAI Codex Rust 代码库中提取的编码模式 - 一个具有严格错误处理、异步模式和 workspace 组织的生产 CLI/代理系统
OpenAI Codex Rust CLI 代理最佳实践
本技能教你以 OpenAI Codex 代码库的风格编写 Rust 代码 - 这是一个包含 50 个 crate 和 787 个 Rust 文件的生产 CLI/代理系统。
关键特性
- Edition 2024 带有严格的 Clippy 配置
- 非测试代码中零 unwrap/expect(在 workspace 级别强制执行)
- Tokio 异步运行时,带有适当的 Send + Sync 边界
- thiserror 用于库错误,anyhow 用于应用程序代码
- 扁平 workspace 结构,带有集中化的依赖管理
适用场景
在以下情况应用此技能:
- 使用 Rust 构建 CLI 工具或代理系统
- 编写使用 Tokio 的异步 Rust 代码
- 设计 Rust workspace 组织
- 实现错误处理模式
- 处理生产 Rust 代码库
快速参考
关键规则(必须遵循)
| 规则 | 描述 |
|---|---|
| err-no-unwrap | 在非测试代码中绝不使用 unwrap() |
| err-no-expect | 在库代码中避免使用 expect() |
| err-thiserror-domain | 使用 thiserror 处理领域错误 |
| err-context-chain | 使用 .context() 为错误添加上下文 |
错误处理
| 规则 | 描述 |
|---|---|
| err-anyhow-application | 使用 anyhow::Result 作为入口点 |
| err-from-derive | 使用 #[from] 进行错误转换 |
| err-transparent | 使用 #[error(transparent)] 包装错误 |
| err-structured-variants | 在错误变体中包含相关数据 |
| err-io-result | 为 I/O 函数使用 std::io::Result |
| err-map-err-conversion | 使用 map_err 进行错误转换 |
| err-doc-errors | 文档化错误条件 |
组织
| 规则 | 描述 |
|---|---|
| org-workspace-flat | 扁平 workspace 带有 utils 子目录 |
| org-crate-naming | kebab-case 目录,项目前缀 |
| org-module-visibility | 使用 pub(crate) 用于内部 API |
| org-test-common-crate | 共享测试工具 crate |
| org-integration-tests-suite | 在 suite 目录中进行测试 |
| org-feature-modules | 基于特性的模块组织 |
| org-handlers-subdir | 在专用子目录中处理 handlers |
| org-errors-file | 在专用文件中定义错误 |
组件模式
| 规则 | 描述 |
|---|---|
| mod-derive-order | 一致的 derive 宏顺序 |
| mod-async-trait-macro | 使用 #[async_trait] 用于异步 traits |
| mod-trait-bounds | Send + Sync + 'static 用于并发 traits |
| mod-extension-trait-suffix | Ext 后缀用于扩展 traits |
| mod-builder-pattern | Builder 模式用于复杂配置 |
| mod-type-alias-complex | 类型别名用于复杂泛型 |
| mod-impl-block-order | 一致的 impl 块顺序 |
| mod-generic-constraints | Where 子句用于复杂边界 |
| mod-newtype-pattern | Newtype 模式用于类型安全 |
| mod-struct-visibility | 私有字段带公共构造函数 |
| mod-serde-rename | Serde rename 用于线格式 |
| mod-jsonschema-derive | JsonSchema 用于 API 类型 |
命名约定
| 规则 | 描述 |
|---|---|
| name-async-no-suffix | 异步函数无 _async 后缀 |
| name-try-prefix-fallible | try_ 前缀用于易错构造函数 |
| name-with-prefix-builder | with_ 前缀用于 builder 方法 |
| name-handler-suffix | Handler 后缀用于 handlers |
| name-error-suffix | Error 后缀用于错误类型 |
| name-result-type-alias | Crate 特定的 Result 别名 |
| name-const-env-var | _ENV_VAR 后缀用于环境常量 |
| name-request-response | Request/Response 类型配对 |
| name-options-suffix | Options 后缀用于配置包 |
| name-info-suffix | Info 后缀用于只读数据 |
| name-provider-suffix | Provider 后缀用于服务 |
| name-client-suffix | Client 后缀用于 API 客户端 |
| name-manager-suffix | Manager 后缀用于生命周期管理 |
| name-bool-is-prefix | is_/has_/should_ 用于布尔值 |
| name-plural-collections | 复数名称用于集合 |
风格
| 规则 | 描述 |
|---|---|
| style-import-granularity | 每个 use 语句一个项目 |
| style-deny-stdout | 在库中拒绝 stdout/stderr |
| style-inline-format-args | 内联格式参数 |
| style-module-docs | 模块级文档 |
| style-expect-reason | #[expect] 带有 lint 原因 |
| style-cfg-test-module | 单元测试在 mod tests 中 |
跨 Crate
| 规则 | 描述 |
|---|---|
| cross-workspace-lints | Workspace 级 lint 配置 |
| cross-workspace-deps | 集中化的依赖版本 |
示例:正确的错误处理
use thiserror::Error;
use anyhow::Context;
// 使用 thiserror 的领域错误
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("failed to read config file: {path}")]
ReadFailed {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error(transparent)]
Parse(#[from] toml::de::Error),
}
// 库函数返回领域错误
pub fn load_config(path: &Path) -> Result<Config, ConfigError> {
let content = fs::read_to_string(path)
.map_err(|source| ConfigError::ReadFailed {
path: path.to_owned(),
source,
})?;
toml::from_str(&content).map_err(Into::into)
}
// 应用程序代码使用 anyhow 带上下文
fn main() -> anyhow::Result<()> {
let config = load_config(Path::new("config.toml"))
.context("failed to load configuration")?;
run(config).await
}
来源
模式提取自 OpenAI Codex (codex-rs/ 子目录) - 一个包含 50 个 crate 和 787 个 Rust 文件的生产 Rust 代码库。