mcpField
R
rust-best-practices

rust-best-practices

github.com/apollographql開発12121.3k 回インストール1 日前に更新
リポジトリ

rust-best-practices について

rust-best-practicesは、Apollo GraphQLのRustベストプラクティスハンドブックに基づく、Rustコードの作成とレビュー向けスキルです。イディオム、エラー処理、性能、テスト、型、ドキュメントを扱います。

主な機能

  1. 01所有権と借用の指針
  2. 02エラー処理の規約
  3. 03性能とlintの助言
  4. 04テストの推奨事項
  5. 05ジェネリクスと型状態の指針
  6. 06ドキュメント作成の実践

活用シーン

  1. 01Rustのイディオムに沿ったコードレビュー
  2. 02エラー処理方法の選択
  3. 03性能とClippyの懸念点の確認
  4. 04テストとAPIドキュメントの計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/apollographql/skills --skill rust-best-practices

インストール後、Claude Code で/rust-best-practicesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
chapter_01.md
chapter_02.md
chapter_03.md
chapter_04.md
chapter_05.md
chapter_06.md
chapter_07.md
chapter_08.md
chapter_09.md

詳細

Rust のベストプラクティス

Rust コードを記述またはレビューする際は、以下のガイドラインを適用してください。Apollo GraphQL の[Rust ベストプラクティスハンドブック](https://github.com/apollographql/rust-best-practices)に基づいています。

ベストプラクティスの参照資料

レビューの前に、Apollo の Rust ベストプラクティスを確認してください。同じターン内に、該当するすべての章を並行して読んでください。フィードバックを提供する際は、以下のファイルを参照してください。

  • [第 1 章 - コーディングスタイルとイディオム](references/chapter_01.md):借用とクローンの使い分け、Copy トレイト、Option/Result の扱い、イテレーター、コメント、関数を切り出すタイミング(重複か、不適切な抽象化か)
  • [第 2 章 - Clippy とリンティング](references/chapter_02.md):Clippy の設定、重要な lint、ワークスペースでの lint 設定
  • [第 3 章 - パフォーマンスを意識した考え方](references/chapter_03.md):プロファイリング、冗長なクローンの回避、スタックとヒープ、ゼロコスト抽象化
  • [第 4 章 - エラー処理](references/chapter_04.md):Result と panic の使い分け、thiserror と anyhow の使い分け、エラー階層
  • [第 5 章 - 自動テスト](references/chapter_05.md):テストの命名、テストごとに 1 つのアサーション、スナップショットテスト
  • [第 6 章 - ジェネリクスとディスパッチ](references/chapter_06.md):静的ディスパッチと動的ディスパッチ、トレイトオブジェクト
  • [第 7 章 - 型状態パターン](references/chapter_07.md):コンパイル時の状態安全性、使用するタイミング
  • [第 8 章 - コメントとドキュメント](references/chapter_08.md):コメントを付けるタイミング、ドキュメントコメント、rustdoc
  • [第 9 章 - ポインターを理解する](references/chapter_09.md):スレッド安全性、Send/Sync、ポインターの型

クイックリファレンス

借用と所有権
  • 所有権の移動が必要でない限り、.clone() よりも &T を優先します
  • 関数の引数には、String よりも &str を、Vec<T> よりも &[T] を使います
  • 小さな Copy 型(≤24 bytes)は、値渡しにできます
  • 所有権が明確でない場合は、Cow<'_, T> を使います
エラー処理
  • 失敗する可能性のある処理では Result<T, E> を返し、本番コードでの panic! は避けます
  • テスト以外では unwrap()/expect() を使わないでください
  • ライブラリのエラーには thiserror を、バイナリに限って anyhow を使います
  • エラーの伝播には、match の連鎖よりも ? 演算子を優先します
パフォーマンス
  • ベンチマークは必ず --release フラグを付けて実行します
  • パフォーマンスに関するヒントを得るには、cargo clippy -- -D clippy::perf を実行します
  • ループ内でのクローンは避けます。Copy 型では .into_iter() よりも .iter() を使います
  • 手動のループよりもイテレーターを優先し、中間の .collect() 呼び出しは避けます
リンティング

定期的に実行します:cargo clippy --all-targets --all-features --locked -- -D warnings

注意すべき主な lint:

  • redundant_clone - 不要なクローン
  • large_enum_variant - 大きすぎるバリアント(ボックス化を検討)
  • needless_collect - 早すぎるコレクション化

正当化するコメントを添えて、#[allow(...)] よりも #[expect(clippy::lint)] を使います。

テスト
  • わかりやすい名前を付けます:process_should_return_error_when_input_empty()
  • 可能な限り、テストごとにアサーションは 1 つにします
  • 公開 API の例にはドキュメントテスト(///)を使います
  • 生成された出力のスナップショットテストには、cargo insta の使用を検討します
ジェネリクスとディスパッチ
  • パフォーマンスが重要なコードでは、ジェネリクス(静的ディスパッチ)を優先します
  • 異種コレクションが必要な場合に限り、dyn Trait を使います
  • 内部ではなく、API の境界でボックス化します
型状態パターン

型システムで有効な状態を表現し、無効な操作をコンパイル時に検出します:

struct Connection<State> { /* ... */ _state: PhantomData<State> }
struct Disconnected;
struct Connected;

impl Connection<Connected> {
    fn send(&self, data: &[u8]) { /* only connected can send */ }
}
ドキュメント
  • // コメントでは「なぜ」を説明します(安全性、回避策、設計上の根拠)
  • /// ドキュメントコメントでは、公開 API の「何を」と「どのように」を説明します
  • すべての TODO には、関連する issue をリンクします:// TODO(#42): ...
  • ライブラリでは #![deny(missing_docs)] を有効にします

コメント