Files
affaan-m--everything-claude…/docs/ja-JP/rules/rust/coding-style.md
T
wehub-resource-sync d48cda4081
CI / Test (ubuntu-latest, Node 18.x, bun) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, npm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, pnpm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, yarn) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 20.x, bun) (push) Failing after 17m13s
CI / Test (ubuntu-latest, Node 20.x, npm) (push) Failing after 18m42s
CI / Test (ubuntu-latest, Node 20.x, pnpm) (push) Failing after 15m0s
CI / Test (ubuntu-latest, Node 20.x, yarn) (push) Failing after 49m44s
CI / Test (ubuntu-latest, Node 22.x, bun) (push) Failing after 51m55s
CI / Test (ubuntu-latest, Node 22.x, pnpm) (push) Failing after 21m57s
CI / Test (ubuntu-latest, Node 22.x, npm) (push) Failing after 37m39s
CI / Test (ubuntu-latest, Node 22.x, yarn) (push) Failing after 34m7s
CI / Validate Components (push) Failing after 37m15s
CI / Python Tests (push) Failing after 10m1s
CI / Security Scan (push) Failing after 10m1s
CI / Lint (push) Failing after 17m12s
CI / Coverage (push) Failing after 20m19s
CI / Test (macos-latest, Node 18.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, yarn) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 11:55:55 +08:00

152 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
paths:
- "**/*.rs"
---
# Rust コーディングスタイル
> このファイルは [common/coding-style.md](../common/coding-style.md) を Rust 固有のコンテンツで拡張します。
## フォーマット
- 強制には **rustfmt** を使用 — コミット前に必ず `cargo fmt` を実行する
- リントには **clippy** を使用 — `cargo clippy -- -D warnings`(警告をエラーとして扱う)
- 4スペースインデント(rustfmt デフォルト)
- 最大行幅: 100文字(rustfmt デフォルト)
## 不変性
Rust の変数はデフォルトで不変 — これを活用する:
- デフォルトで `let` を使用する。ミューテーションが必要な場合にのみ `let mut` を使用する
- その場でのミューテーションよりも新しい値を返すことを優先する
- 関数が割り当てる必要があるかどうかわからない場合は `Cow<'_, T>` を使用する
```rust
use std::borrow::Cow;
// 良い例 — デフォルトで不変、新しい値を返す
fn normalize(input: &str) -> Cow<'_, str> {
if input.contains(' ') {
Cow::Owned(input.replace(' ', "_"))
} else {
Cow::Borrowed(input)
}
}
// 悪い例 — 不要なミューテーション
fn normalize_bad(input: &mut String) {
*input = input.replace(' ', "_");
}
```
## 命名
標準的な Rust の規約に従う:
- 関数、メソッド、変数、モジュール、クレートには `snake_case`
- 型、トレイト、列挙型、型パラメータには `PascalCase`UpperCamelCase
- 定数とスタティックには `SCREAMING_SNAKE_CASE`
- ライフタイム: 短い小文字(`'a``'de`)— 複雑な場合は説明的な名前(`'input`
## 所有権と借用
- デフォルトで借用(`&T`)する。格納または消費する必要がある場合にのみ所有権を取得する
- 根本原因を理解せずにボローチェッカーを満たすためにクローンしない
- 関数パラメータでは `String` よりも `&str``Vec<T>` よりも `&[T]` を受け入れる
- `String` を所有する必要があるコンストラクタには `impl Into<String>` を使用する
```rust
// 良い例 — 所有権が不要な場合は借用する
fn word_count(text: &str) -> usize {
text.split_whitespace().count()
}
// 良い例 — Into を使用してコンストラクタで所有権を取得する
fn new(name: impl Into<String>) -> Self {
Self { name: name.into() }
}
// 悪い例 — &str で十分なのに String を取得する
fn word_count_bad(text: String) -> usize {
text.split_whitespace().count()
}
```
## エラーハンドリング
- 伝搬には `Result<T, E>``?` を使用する — 本番コードでは `unwrap()` を使わない
- **ライブラリ**: `thiserror` で型付きエラーを定義する
- **アプリケーション**: 柔軟なエラーコンテキストには `anyhow` を使用する
- `.with_context(|| format!("failed to ..."))?` でコンテキストを追加する
- `unwrap()` / `expect()` はテストと本当に到達不可能な状態にのみ使用する
```rust
// 良い例 — thiserror によるライブラリエラー
#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
#[error("failed to read config: {0}")]
Io(#[from] std::io::Error),
#[error("invalid config format: {0}")]
Parse(String),
}
// 良い例 — anyhow によるアプリケーションエラー
use anyhow::Context;
fn load_config(path: &str) -> anyhow::Result<Config> {
let content = std::fs::read_to_string(path)
.with_context(|| format!("failed to read {path}"))?;
toml::from_str(&content)
.with_context(|| format!("failed to parse {path}"))
}
```
## ループよりもイテレータ
変換にはイテレータチェーンを優先する。複雑な制御フローにはループを使用する:
```rust
// 良い例 — 宣言的で合成可能
let active_emails: Vec<&str> = users.iter()
.filter(|u| u.is_active)
.map(|u| u.email.as_str())
.collect();
// 良い例 — 早期リターンを伴う複雑なロジックにはループ
for user in &users {
if let Some(verified) = verify_email(&user.email)? {
send_welcome(&verified)?;
}
}
```
## モジュール構成
型ごとではなく、ドメインごとに整理する:
```text
src/
├── main.rs
├── lib.rs
├── auth/ # ドメインモジュール
│ ├── mod.rs
│ ├── token.rs
│ └── middleware.rs
├── orders/ # ドメインモジュール
│ ├── mod.rs
│ ├── model.rs
│ └── service.rs
└── db/ # インフラストラクチャ
├── mod.rs
└── pool.rs
```
## 可視性
- デフォルトはプライベート。内部共有には `pub(crate)` を使用する
- クレートのパブリック API の一部であるものだけに `pub` を付ける
- `lib.rs` からパブリック API を再エクスポートする
## 参考
包括的な Rust のイディオムとパターンについてはスキル: `rust-patterns` を参照。