はじめに
Rust のライブラリシステムについて逆引きで探せるドキュメントがあるとうれしいと思ったのでまとめてみました。
用語
- Rust ではライブラリのパッケージのことをクレートと呼び、クレート内のコードのまとまりをモジュールと呼びます。
-
std::vec::Vec
はstd
クレートのstd::vec
モジュールのVec
構造体です。
ライブラリ用のプロジェクトを作成する
-
cargo new
コマンドに--lib
オプションを付けて実行するとライブラリ用のプロジェクトが作成できます
# greeting プロジェクトを作成する
$ cargo new phrases --lib
# ファイル構成
$ cd phrases
$ find .
./Cargo.toml
./src
./src/lib.rs
モジュールを作成する
-
src/lib.rs
へpub mod
でモジュールを定義し、モジュールと同名のファイルでモジュールの実装をしていきます。
src/lib.rs
// phrases::english モジュールの宣言
pub mod english;
src/english.rs
// phrases::english::hello の定義
pub fn hello() -> String {
"Hello!".to_string()
}
同一プロジェクトからモジュールを利用する
-
src/main.rs
を作成して同一プロジェクトから作成したクレートを利用します。 -
src/main.rs
はアプリケーション用の実行ファイルとして扱われcargo run
で実行可能になります
src/main.rs
fn main() {
assert_eq!(phrases::english::hello(), "Hello!".to_string());
}
サブモジュールを作成する
- 親モジュールの実装ファイル内でサブモジュールの定義を行い、親モジュールと同じ名前のディレクトリを用意し、その下のサブモジュール名のファイルで実装を定義します。
src/lib.rs
// 親モジュール phrases::english の宣言
pub mod english;
src/english.rs
// 子モジュール phrases::english::greetings の宣言
pub mod greetings;
// 子モジュール phrases::english::farewells の宣言
pub mod farewells;
src/english/greetings.rs
pub fn hello() -> String {
"Hello!".to_string()
}
src/french/farewells.rs
pub fn goodbye() -> String {
"Goodbye!".to_string()
}
src/main.rs
fn main() {
// モジュールを利用する
assert_eq!(phrases::english::greetings::hello(), "Hello!".to_string());
assert_eq!(phrases::english::farewells::goodbye(), "Goodbye!".to_string());
}
ライブラリのテストを書く
- ライブラリのユニットテストは個々の実装ファイルなどで
#[test]
属性を付けた関数として実装します。
src/english/greetings.rs
pub fn hello() -> String {
"Hello!".to_string()
}
#[test]
fn test_hello() {
assert_eq!(hello(), "Hello!".to_string());
}
- ライブラリの結合テストは
tests
ディレクトリにテスト関数を実装した .rs ファイルを置いて実装します。 - ライブラリの外部からのテストになるので
extern crate
でクレートを読み込みます
tests/english.rs
extern crate phrases;
#[test]
fn test_greetings_hello() {
assert_eq!(phrases::english::greetings::hello(), "Hello!".to_string());
}
#[test]
fn test_farewells_goodbye() {
assert_eq!(phrases::english::farewells::goodbye(), "Goodbye!".to_string());
}
ライブラリのドキュメントを書く
- クレートの説明は
src/lib.rs
に//!
を行頭につけたドキュメンテーションコメントとして記載します。 - ドキュメンテーションコメントは Markdown 記法をサポートします
src/lib.rs
//! # phrases
//! This is sample code.
pub mod english;
- モジュールの説明は
src/english.rs
などモジュールの定義ファイルに//!
を行頭につけたドキュメンテーションコメントとして記載します。 - 関数の説明は各関数の定義の上に
///
を行頭につけたドキュメンテーションコメントとして記載します。
src/english.rs
//! # phrases::english
//! This is sample
///return "Hello!"
pub fn hello() -> String {
"Hello!".to_string()
}
- ドキュメントの確認は
cargo doc
で行います。--open
はドキュメントをブラウザで開くためのもので--no-deps
は依存関係にあるクレートのドキュメントは生成しないというものです
argo doc --open --no-deps
ライブラリを別のプロジェクトから利用する
- ライブラリを github.com などにアップロードし Cargo.toml に依存関係を定義して利用します。
- ブランチ、タグ、リビジョンなどの指定もできます。
Cargo.toml
[dependencies]
phrases = { git = "https://github.com/nirasan/phrases" }
# phrases = { git = "https://github.com/nirasan/phrases", branch = "master" }
# phrases = { git = "https://github.com/nirasan/phrases", tag = "v1.0.0" }
# phrases = { git = "https://github.com/nirasan/phrases", rev = "10cf8da" }
src/main.rs
extern crate phrases;
fn main() {
println!("{}", phrases::english::hello());
}