跳到正文
cccskills
免费在 GitHub 公开中文介绍

rust-code-style

本技能帮助编写和审查仓库构建工具中的 Rust 代码,涵盖命令行设计、错误处理、类型、格式、测试、依赖与 Bazel 检查,并区分自动化工具和面向用户的命令。

原文查看原文说明

Write or review Rust in the build tools.

JetBrains/intellij-community星标 20,685(GitHub 20,685 + cccskills 0)

实测评分 未实测

查看安装方法

适用场景

  • 实现 Rust 构建工具
  • 审查命令行错误和退出码
  • 确认 Rust 与 Bazel 的检查步骤

中文介绍

功能

本技能整理了构建工具中 Rust 工作区的专用约定。首先判断工具是由 Bazel 调用的自动化动作工具,还是供人员或代理使用的命令行工具,然后采用相应的参数格式和错误处理方式。内容涵盖路径类型、为错误补充上下文、Lint 例外写法、拆分 crate 的条件,以及测试和测试数据的存放位置。技能还列出了修改前后需要执行的检查,包括 cargo fmt、Clippy、Bazel 同步与构建检查,以及面向 Windows 的检查。

适用场景

修改 dev-dist tools、BT 或 Air UI-lane tooling 等 Rust 工作区,或者检查现有代码是否符合命令行行为、错误处理和测试规范时,可以使用本技能。

使用示例

  • “请按工作区规范调整这个 Rust 命令的参数处理。”
  • “请审查错误处理和退出码设计。”
  • “请整理修改后需要执行的 Rust 和 Bazel 检查。”

注意事项

本技能适用于资料中列出的仓库内 Rust 工具工作区。验证需要 Rust、Bazel、Bun 环境,以及各工作区对应的命令。

本介绍由 AI(OpenAI Codex)根据公开的 SKILL.md 撰写。准确的规格请查看下方原文。

文档检查

AI 根据 SKILL.md 的内容检查了需要注意的操作和使用前提。评分只依据实际运行的结果(实测对比)。

安全性发送数据、删除文件、执行命令等是否有说明
A良好资料说明拒绝输入的处理、退出码及受限的 Windows 敏感 API。
安装难易度所需工具和 API 密钥是否少且有说明
B部分不足资料指出需要 Rust、Bazel、Bun 及各工作区对应的命令。

不计入评分。 由 AI(OpenAI Codex)于 2026年10月28日 评估。仅供参考,安装前请同时查看原文。

如果您认为评估有误,请申请复核

请写明哪一项有误以及原因。无需登录。我们会对照 SKILL.md 重新评估,并在此处更新结果。

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

包含的文件(1)

  • SKILL.md9.5 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

<!-- Generated by community/.ai/render-guides.mjs; edit community/.agents/skills/rust-code-style/SKILL.md -->

Rust Code Style

These rules apply to the Rust tool workspaces: the dev-dist tools, BT and the Air UI-lane tooling. The spec of a workspace is community/build/rust-tools/README.md. It names the files, the Bazel targets and the checks that every workspace has. This skill holds the idioms.

First, find the audience

A tool has one of two audiences. The audience picks the error model and the command line grammar.

Action toolPerson- or agent-facing CLI
Writes the command lineBazel, in an actiona person, an agent or a script
Examplesthe packer, the collector, the composer, the descriptor writerbt, vm
Error modelanyhow, ERROR: {e:#}, a nonzero exita typed Refusal with a stable code and exit
Command linethe cli crate, --key=valueclap derive
Crate closurepinned in closure.txtnot pinned

Bazel reads only "nonzero" from an action tool. A person or an agent branches on the exit code and on the refusal code.

1. Two error models

An action tool returns anyhow::Result from every function and prints the chain once. main.rs stays thin:

fn main() -> ExitCode {
    ExitCode::from(run(std::env::args_os().skip(1), &mut std::io::stdout(), &mut std::io::stderr()))
}

run calls the tool and passes an error to cli::report, which prints ERROR: {error:#}. Each tool keeps its own exit codes. bins/runtime-layout/src/main.rs of the dev-dist tools shows the shape.

A person- or agent-facing CLI answers a Refusal { code, message, exit, details }. The code is the stable half that a caller automates against. The shared crate community/tools/bt/crates/refusal holds the type, with the details as JSON text. Its type parameter is the exit vocabulary, so each tool keeps its own exit codes: bt uses u8 with the codes 0 to 6 of community/tools/bt/crates/bt-core/src/exit.rs, and the Air UI-lane controller uses avl_base::Exit. A tool that converts a refusal of another tool maps the exit by its meaning, never by its number.

2. Two command line grammars

Bazel writes the argv of an action tool, so the tool reads it with the cli crate. The crate has no dependency, and it refuses every other form with one text. community/build/dev-dist-tools/crates/cli/API.md lists the refusals.

let mut options = cli::parse(args)?;
let output = options.require("--output")?;
let parts = options.take_all("--part")?;
options.finish()?; // refuses an option that the tool did not take

A person- or agent-facing CLI uses clap derive: help, environment variables, suggestions and -- passthrough. community/tools/bt/bins/bt/src/options.rs is the example. Use no third grammar and no hand-written argument loop.

3. Format

  • The width is 140 columns, as in the root .editorconfig. The synced rustfmt.toml of each workspace sets it.
  • Run cargo fmt in the workspace directory before every commit.
  • Format a whole workspace in its own commit, without other changes.

4. Lints

  • Every crate follows the shared table: [lints] workspace = true in its Cargo.toml. The crate macro fails without it.
  • A site exception is #[expect(lint, reason = "...")], never #[allow]. An expectation that stops firing fails the build, so a stale exception shows.
  • clippy.toml bans fs::canonicalize and the tempfile calls that fail past MAX_PATH on Windows. A site that needs a banned call states why:
#[expect(
    clippy::disallowed_methods,
    reason = "the parent resolves the expected directory with the same call, so both sides agree on /private on macOS"
)]

5. Errors in libraries

  • Use anyhow in a library too. Use io::Result only where a caller branches on the ErrorKind, as fscopy does.
  • A refusal names the refused input: the file, the line, the field or the value.
  • Add the path as context at the I/O call: .with_context(|| format!("cannot read {}", path.display())).
  • A test pins the whole chain with format!("{error:#}"). A test that checks a kind uses error.downcast_ref::<io::Error>().

6. Types

  • Use an enum where a Go port used flags or a struct of options. A match then covers every case.
  • Use Path and PathBuf for every host path. Use str only for a slash-form path inside a distribution or a jar. distpath validates such a path once, at the input boundary.
  • Write pub(crate) inside a binary. The unreachable_pub lint is on.
  • Keep main.rs thin: parse, call, report. The work lives in modules that the tests call directly.

7. Crates

  • A crate exists when two binaries share it, or when it is the frozen-bytes engine of one binary with its own goldens. Code that one binary uses lives in that binary.
  • An action tool pins its crate closure in closure.txt, such as community/build/dev-dist-tools/bins/content-module-packer/closure.txt. A change to any crate in the closure reruns every action of the tool, so <bin>_closure_test makes each new crate a visible choice.
  • Prefer a maintained crate to own code. The exception is a crate that would re-key an action tool, when about 30 lines replace it. State the reason in one sentence of the doc comment:
/// It is written by hand, because a crate dependency in the packer re-keys every packing action when the crate changes.
pub(crate) fn is_versioned_module_info(name: &str) -> bool {
  • Support the subset: a tool accepts only the input that the repository produces. It refuses all other input with an error that names the input. The API.md of the crate lists each refusal.

8. Tests

  • <module>.rs ends with #[cfg(test)] mod tests;, and the tests live in <module>/tests.rs. The tests of lib.rs or main.rs live in src/tests.rs. There is no mod.rs: mod_module_files is on.
  • The process-level tests of a binary live in tests/cli.rs. The run-time CARGO_BIN_EXE_<name> gives the binary. Under Bazel the path is relative, so make it absolute before the test changes the directory.
  • Shared test helpers live in a dev-only testkit crate. Shipped code never depends on it.
  • A test finds testdata/ through one lookup: the variable that the crate macro sets under Bazel, such as DDT_TESTDATA_DIR, and the run-time CARGO_MANIFEST_DIR under cargo. The rules_rust process wrapper refuses env!("CARGO_MANIFEST_DIR"). A file that include_str! reads is compile_data of the crate.
  • Never edit a golden by hand. Regenerate it with the update path of its test.
  • The Windows check is the clippy-windows-* targets of the workspace and the cross-target cargo clippy below.

9. Docs

  • The README.md of a workspace holds the crate map and the gates.
  • The API.md of a crate under the subset rule holds the supported subset and a refusal table.
  • A doc comment documents a declaration. The rationale of a change goes in the commit message or an ADR, not in a comment.

10. Versions

  • A requirement names the current full version, such as serde = "1.0.229". Cargo reads it as a caret requirement.
  • Cargo.lock is the pin, and rules_rs reads it.
  • To stay current, run cargo update, raise the requirements to the locked versions, and refresh the hub.

Refresh a crate hub

community/MODULE.bazel generates @ddt and @bt from the workspace Cargo.toml and Cargo.lock. After a change of Cargo.lock, update the Bazel lockfiles of both roots. For the dev-dist tools:

cd community && ./bazel.cmd build --nobuild --lockfile_mode=update //build/dev-dist-tools/...
cd .. && ./bazel.cmd build --nobuild --lockfile_mode=update @community//build/dev-dist-tools/... //build/dev-dist-tools/...

For BT, use //tools/bt/... and @community//tools/bt/.... The extension watches only the workspace Cargo.toml and Cargo.lock. A dependency that moves between [dev-dependencies] and [dependencies] of a member leaves the lock unchanged. Then touch the workspace Cargo.toml, for example with a comment line, and run the commands again.

The gates

Run them before a commit, in addition to the gates of the workspace README:

cargo fmt --check && cargo clippy --all-targets      # in the workspace directory
bun community/build/rust-tools/sync.mjs --check
cd community && ./bazel.cmd test //build/dev-dist-tools/... //tools/bt/... //build/rust-tools/...
RUSTC_BOOTSTRAP=1 cargo clippy -Zbuild-std=std,panic_abort --target x86_64-pc-windows-msvc --workspace --all-targets

From the ultimate root, also run ./bazel.cmd test @community//build/dev-dist-tools/... //build/dev-dist-tools/.... The clippy tests of a community crate run only from community/, because the clippy aspect skips a target of an external repository.

Where things live

WhatWhere
The spec of a workspace, the checks, how a workspace joinscommunity/build/rust-tools/README.md
The lint, format and clippy sources, and sync.mjscommunity/build/rust-tools/
The Bazel macro core: rust_tool_crate, optimized_binary, windows_clippy_testscommunity/build/rust-tools/defs.bzl
The dev-dist tools: crate map, gates, agent rulescommunity/build/dev-dist-tools/README.md and AGENTS.md
BTcommunity/tools/bt/README.md
The Air UI-lane tooling: crate map, gates, agent rulescommunity/tools/vm/README.md and AGENTS.md

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

actions

免费有简介

实现或修改 IntelliJ `AnAction`,并在 `plugin.xml` 中注册。将显示名称和说明写入消息资源文件,按需设置图标,并通过事件协程作用域启动挂起任务,避免同步处理阻塞 IDE。

  • 为 IDE 菜单添加操作
  • 修改操作注册或图标
  • 整理操作名称和说明
JetBrains/intellij-community2.1万2026年10月29日 更新

bazel-test-migration

免费有简介

将 IntelliJ JPS 测试模块迁移到 Bazel,并排查仅在 Bazel 中出现的失败。根据症状检查依赖、插件、测试数据和 runfiles,重新生成并验证目标。

  • 将 JPS 测试模块迁移到 Bazel
  • 排查仅在 Bazel 中失败的测试
  • 检查测试依赖和数据配置
JetBrains/intellij-community2.1万2026年10月29日 更新

code-style

免费有简介

按 IntelliJ 项目规范编写或审查 Kotlin 和 Java 代码,涵盖语言选择、格式、密封类型、线程注解及控制流异常处理。

  • 按 IntelliJ 规范编写 Kotlin
  • 审查 Java 代码
  • 检查异常处理和密封类型分支
JetBrains/intellij-community2.1万2026年10月29日 更新

commits

免费有简介

本指南帮助您按 IntelliJ 项目规则拆分更改并撰写提交信息:有工单时使用编号和变更说明,无工单时使用标签与子系统名,并在需要时说明原因和决定。

  • 按项目格式编写带工单号的提交信息
  • 整理测试或文档提交并选择合适标签
  • 按规则修改已有提交信息
JetBrains/intellij-community2.1万2026年10月29日 更新

使用多个 Python 类型检查器比较代码片段或文件的类型推断和报错判断,并汇总各工具的结论、耗时与诊断信息,可保存为 Markdown 报告。

  • 比较不同检查器的类型推断
  • 确认代码是否会被判为类型错误
  • 查看多个工具的诊断差异
JetBrains/intellij-community2.1万2026年10月29日 更新

整理 Compose Desktop 界面中的状态和副作用,让可组合函数负责绘制,由展示器或协调器处理应用决策。了解状态归属、Effect、可复用组件接口、延迟列表键、动画和性能,适用于单项界面修改。

  • 分离界面绘制与展示器决策
  • 整理界面状态的归属
  • 检查 Effect 键和协程用法
JetBrains/intellij-community2.1万2026年10月29日 更新

查看 JetBrains 的全部技能

报告此技能的问题