簡単なドキュメントの初期化
説明
ドキュメントを書く際に構造体の初期化にかなりの手間がかかる場合は、その構造体を引数として受け取るヘルパー関数でサンプルをラップすると、より素早く書けます。
動機
複数または複雑なパラメーターと、いくつかのメソッドを持つ構造体があることがあります。これらの各メソッドにはサンプルがあるべきです。
たとえば、次のようになります。
struct Connection {
name: String,
stream: TcpStream,
}
impl Connection {
/// 接続経由でリクエストを送信します。
///
/// # 例
/// ```no_run
/// # // サンプルを動作させるには定型コードが必要です。
/// # let stream = TcpStream::connect("127.0.0.1:34254");
/// # let connection = Connection { name: "foo".to_owned(), stream };
/// # let request = Request::new("RequestId", RequestType::Get, "payload");
/// let response = connection.send_request(request);
/// assert!(response.is_ok());
/// ```
fn send_request(&self, request: Request) -> Result<Status, SendErr> {
// ...
}
/// なんということでしょう、そのすべての定型コードをここでも繰り返す必要があります!
fn check_status(&self) -> Status {
// ...
}
}
例
Connection と Request を作成するためにこれらすべての定型コードを入力する代わりに、それらを引数として受け取るラップ用のヘルパー関数を作成するだけのほうが簡単です。
struct Connection {
name: String,
stream: TcpStream,
}
impl Connection {
/// 接続経由でリクエストを送信します。
///
/// # 例
/// ```
/// # fn call_send(connection: Connection, request: Request) {
/// let response = connection.send_request(request);
/// assert!(response.is_ok());
/// # }
/// ```
fn send_request(&self, request: Request) -> Result<Status, SendErr> {
// ...
}
}
上記の例では、assert!(response.is_ok()); の行は、呼び出されることのない関数の内側にあるため、テスト時に実際には実行されないことに注意してください。
利点
これははるかに簡潔で、サンプル内の繰り返しコードを避けられます。
欠点
サンプルが関数内にあるため、コードはテストされません。ただし、cargo test を実行すると、コンパイルできることを確認するためのチェックは引き続き行われます。そのため、このパターンは no_run が必要な場合に最も有用です。これにより、no_run を追加する必要がなくなります。
議論
アサーションが不要な場合、このパターンはうまく機能します。
アサーションが必要な場合の代替案として、#[doc(hidden)] で注釈を付けた(ユーザーには表示されないようにする)ヘルパーインスタンスを作成する public メソッドを作成できます。その場合、このメソッドはクレートの public API の一部であるため、rustdoc 内から呼び出すことができます。