---
description: Rustのコードの書き方
globs: *.rs
alwaysApply: true
---

# 基本方針

- Rustの慣例やベストプラクティスに沿ったコードを書きます
- 新しい機能を実装したり既存の機能のコードを修正した場合は、その機能のテストがあるかを確認し、無ければテストを作成します
- 関数名や型名は一貫性、対称性を重視します。
- doc commentでない通常のコメントは、理解が困難なコードにのみ付け、理解が容易なコードにはコメントを付けません
- エラー処理は、バグ以外でErrが返されることがないことが分かっている場合はResultを使用せず、パニックさせます
- コンパイラの警告が発生した場合は、なにが悪くて警告が発生しているのかを考え、実際にコードが悪いと判断された場合は修正してください

# コンパイルエラーが発生した場合の対処

- 型エラーが発生したときには設計に問題がないか確認し、設計の問題に起因して型エラーが発生している場合は再設計を行います
- 依存関係のバージョンを下げてはなりません
- エラーの修正に失敗した場合は 下記の方法で情報を確認し、その情報を元にエラーの解決方法を考えてください
　- `read_crate_readme` ツールを使用してエラーに関連する crate の readme を確認する
　- `search_crate_source` ツールを使用してエラーに関連する型や関数を検索し、検索結果のファイルを `read_crate_file` ツールで取得して確認する
- 同一個所のエラーの修正に3回連続で失敗した場合はコードを元に戻し、その修正はスキップし、別の場所を修正してください 
- スキップしたエラーのみが残っている場合は、スキップしたエラーの一覧をユーザーに提示し、ユーザーによる修正を待機してください

# テストの書き方

- `tests` フォルダ内のテストでは`mod tests`は不要です。
- publicでない項目のテストを行う場合は、`tests/` ディレクトリにテストを配置するのではなく、実装対象のモジュール内の `tests` モジュールに書きます。
- `tests` モジュールは別のファイルにします。
- 1つのテストでのみ使用する型や関数がある場合は、テスト関数内で定義します
- 複数のテストを追加する際は、一つずつテストを追加し、追加したテストを実行してパスすることを確認してから次のテストを追加してください。
- テストを通す為だけに、テストケースの入力のみで処理を変えてはなりません
- テストデータを作成する際は英語のデータを作成して下さい。ただし、非ASCII文字のテストを行う場合は英語以外のデータを作成しても良いです。

# doc commentの書き方

- `mod xxx;` のように独立したファイルで定義されたモジュールの場合は、そのモジュールの子項目が定義されたファイルを開き、そのファイルの先頭に `//!` 形式のコメントを書きます。それ以外は項目の前に `///` 形式のコメントを書きます。
- 項目に属性がついている場合は、属性の後ではなく、前にコメントを書きます。
- ドキュメントコメントを書く際は、ソースコードや他のドキュメントコメントをよく確認し、正しい内容を書いてください。
- 最初の一行にはその項目を端的に表現する非常に簡潔な1行の説明を書きます
　- 最初の一行は他の項目と同じにならないようにしてください。同じ説明文になってしまう場合は、何が違うのかを考え、それぞれに異なる説明を設定してください。
- 最初の一行を含め、全てのドキュメントコメントでは一貫性のある表現を使用してください
- 最初の1行とシグネチャからその項目の用途が充分に理解できる場合は、1行のコメントのみにしてください
- そうでない場合は、2行目を空行とし、3行目以降に詳細な説明と使用例を書いてください。
- 他の関数や型と関連性がある場合は、説明文の中で関連する関数や型の名前を [``] で囲って使用し、リンクを付けます。
  - 例えば `XXX` 型を作成する `XXXBulder` があった場合、`XXX` 型のドキュメントには `XXXBuilder` のリンクを、`XXXBuilder` のドキュメントには `XXX` のリンクを含めます。
  - 例えば、`XXX` 型が `fn xxx() -> XXX` の戻り値を実装する事のみが目的の場合は `XXX` 型の説明に `fn xxx` のリンクを含めます。この場合、 `fn xxx` のリンクに `XXX` を含める必要はありません。（シグネチャから自動的にリンクされるため）

## 全てのdoc commentの検証

全てのドキュメントコメントを書き終わったら、下記のテストを行います。
書くべきドキュメントコメントが他にも残っている場合は、テストはまだ行わず、ドキュメントの作成を優先します。

- `cargo test --doc` を実行し、ドキュメントコメント中に含まれるコードに間違いがないか確認します
  - 間違いがなくなるまで修正と `cargo test --doc` を繰り返します
- `cargo doc` を実行し、ドキュメント生成時に警告が発生しないかを確認します
  - 警告が無くなるまで修正と `cargo doc` を繰り返します

## doc commentのテスト

- `// #![include_doc("ファイル名", start)]`, `// #![include_doc("ファイル名", end)]`で囲まれた部分は、コマンド `rustdoc-include` を実行することで指定したファイルからコピーされます。指定されたファイルの内容を変更した後、テストを行う際は`rustdoc-include --root <ROOT_DIR>`を実行してください。このコマンドが成功した場合、何もメッセージは出力されず、終了コードが0となります。

## 日本語のコメントの表現

日本語でコメントを書く場合は下記の書き方に従ってください

- 最初の一行では、その項目が名詞で表現できる場合は、名詞で文を終える。例えば `～の型です` ではなく `～の型` のように表現する。

# Default の実装方法

Defaultを実装する場合は、次の順番で実装を試みてください

1. 標準の `#[derive(Defualt)]` を使用
2. `derive-ex` crateの `#[derive(Ex)]` `#[derive_ex(Default)]` を使用した方法
3. 手動での実装 `impl Default for T`


# コマンドの実行方法

仕様書に記載された例と説明文に相違がある場合は、例が正しく説明文の解釈にミスがあると考えてください。

カレントディレクトリは初期のディレクトリから変更せず、コマンド引数で同等の事を行ってください。それが不可能な場合のみ `cd` コマンドを使用が許可されます。
コマンドの実行に問題が発生したら、初期のカレントディレクトリに戻ってください。
