Rust プログラミング 入門

Rust完全ガイド 第8回 エコシステム活用

Rustは言語としての機能だけでなく、開発を効率化する強力なエコシステム によっても支持を集めています。
本記事では、Rustの開発環境を支える中心的存在である Cargo の使い方から、人気ライブラリ(クレート)の活用方法、小規模プロジェクトの設計、そしてCI/CDの導入 まで、実践的な開発に役立つ知識を体系的に学んでいきます。

まず、Cargo.toml を使った依存関係の管理や、cargo test によるテスト駆動開発の基本 を解説します。
次に、tokioserdeclap などのクレートを活用して、実際のプロジェクトでどのようにライブラリを取り入れていくか を紹介します。
最後に、プロジェクトのディレクトリ設計のベストプラクティスや、GitHub Actionsなどを使ったCI/CDの基本的な導入方法 を学び、プロフェッショナルなRust開発の一歩を踏み出しましょう。

これまで習得してきた文法や機能を、よりスケーラブルで実用的な形で活用する力 をこの回で身につけていきましょう。

Cargoと依存関係管理

Rustの開発において、Cargo は欠かせないビルドツール兼パッケージマネージャ です。
プロジェクトの作成、依存ライブラリの管理、ビルド、テスト、ドキュメント生成など、開発のあらゆる工程を効率化してくれます。

この章では、まず Cargo.toml を用いた依存関係の定義と管理方法 を解説し、
次に cargo test を活用したテスト駆動開発の基本 を紹介します。

日々の開発において最もよく使う知識ばかりですので、しっかりと理解しておきましょう。

Cargo.tomlの基本

Cargo.tomlとは?

Rustプロジェクトを作成すると、自動的に Cargo.toml という設定ファイルが生成されます。
このファイルは、プロジェクトのメタデータや依存クレートの定義 を記述するためのものです。

基本的な構成

以下は Cargo.toml のシンプルな例です。

[package]
name = "my_project"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = "1.0"
reqwest = { version = "0.11", features = ["json"] }
セクション名内容
[package]パッケージ名、バージョン、Rustエディションなどを記述
[dependencies]使用するクレート(ライブラリ)の依存関係を記述
  • 単純な依存: serde = "1.0" のようにバージョン指定のみ
  • オプション付き依存: featuresdefault-features を指定できる

その他のセクション

  • [dev-dependencies]:開発時だけ使う依存ライブラリを記述(例:テスト用クレート)
  • [build-dependencies]:ビルドスクリプト専用の依存を記述
  • [features]:任意の機能をオン・オフできるカスタム設定

依存の追加方法

ターミナルで以下のように入力すると、自動で Cargo.toml に追記されます。

cargo add clap
cargo add anyhow --features backtrace

cargo-edit クレートがインストールされていない場合は cargo install cargo-edit が必要です。

cargo testによるテスト駆動開発

Rustのテスト文化

Rustには標準でテスト機能が組み込まれており、cargo test コマンドで簡単にテストを実行できます。
関数ごとにテストを書くことが推奨されており、「安心して変更できるコード」を支える文化が根付いています。

基本的なテストの書き方

テストは通常、src/lib.rs または src/main.rs 内に モジュールとして記述 されます。

// src/lib.rs
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(add(2, 3), 5);
    }
}
  • #[cfg(test)]:テスト用モジュールであることを示す
  • #[test]:この関数がテストであることを示す
  • assert_eq!:左と右の値が等しいことをアサートする

テストの実行

ターミナルから以下を実行します。

cargo test

出力例

running 1 test
test tests::test_add ... ok

test result: ok. 1 passed; 0 failed; 0 ignored

テスト駆動開発(TDD)のすすめ

Rustでは、「まずテストを書く → 実装を書く → テストを通す」 という流れで開発を進めるのが非常に効果的です。
型安全とテストの両立によって、不具合の少ない信頼性の高いコード を実現できます。

まとめ

  • Cargo.toml はプロジェクトの情報と依存ライブラリの設定を管理する重要なファイル
  • 依存クレートは [dependencies] に記述し、cargo add コマンドでも追加可能
  • cargo test により、簡単に単体テストを実行できる
  • テスト駆動開発(TDD)はRustと非常に相性がよく、信頼性の高いコードを支える

この章を通じて、Cargoによる依存管理とテストの基礎を習得 できました。
次は、Rustエコシステムの中でも特に活用されている人気クレートの紹介 に進みます。

Rustのパッケージ(Crates.io)

Rustでは、再利用可能なライブラリを 「クレート(crate)」 と呼びます。
Rust公式のパッケージリポジトリである crates.io には、数万以上のクレートが公開されており、誰でも簡単に導入して活用することができます。

クレートを活用することで、自分で実装する必要があった機能を、信頼性の高い既存のライブラリに任せて生産性を大幅に向上させる ことができます。

この章では、Rustの開発現場で特によく使われている代表的なクレート を紹介します。
どれも多くのプロジェクトで採用されている実績あるライブラリなので、ぜひ積極的に使いこなしていきましょう。

人気のクレート紹介 (tokio, serde, clapなど)

1. tokio(非同期処理の基盤)

Rustの非同期処理を支える最も重要なランタイムです。
非同期のHTTP通信やファイルIO、タイマー処理などを効率的に実行するために欠かせません。

  • 非同期関数 async fn.await を使うには tokio が必要
  • 高性能なマルチスレッド対応ランタイムを提供
  • HTTPやWebSocketの実装、TCPサーバー開発にも対応
[dependencies]
tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() {
    println!("非同期処理が可能になりました!");
}

2. serde(シリアライズ/デシリアライズ)

serde は、Rustのデータ構造を JSONやYAML、TOMLなどに変換(シリアライズ)したり、逆に取り込んだり(デシリアライズ) するためのライブラリです。
APIとのデータ連携や設定ファイルの読み込みなど、用途は非常に広く、Rustプロジェクトでは定番中の定番です。

  • JSONだけでなく多くのデータ形式に対応
  • 構造体にアノテーションを付けるだけで自動変換可能
  • serde_json などと組み合わせて使う
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct User {
    id: u32,
    name: String,
}

3. clap(コマンドライン引数パーサー)

CLI(コマンドラインインターフェース)ツールを作成する際に便利なクレートです。
引数の解析、ヘルプメッセージの自動生成、バリデーションなどが非常に簡単に行えます。

  • 直感的なAPIと自動ドキュメント生成が魅力
  • derive マクロで構造体からCLI仕様を記述可能
  • サブコマンドやフラグ、オプションなど多彩な機能をサポート
[dependencies]
clap = { version = "4", features = ["derive"] }"
use clap::Parser;

#[derive(Parser)]
struct Args {
    #[arg(short, long)]
    name: String,
}

fn main() {
    let args = Args::parse();
    println!("こんにちは、{}さん!", args.name);
}

その他おすすめのクレート

クレート名用途説明
anyhowエラーハンドリング開発初期に便利なエラーラップクレート。詳細なトレースが得られる
thiserrorカスタムエラー定義enum で独自エラー型を定義するのに便利
log / tracingログ出力・トレースプロダクション環境でのデバッグ情報出力に活用可能
chrono日付・時刻の扱いタイムゾーン、フォーマット、計算などの高機能サポート

これらは、実務でも頻繁に使われる定番ライブラリです。
必要に応じてプロジェクトに導入し、自分の開発効率とコード品質の向上に活用 していきましょう。

まとめ

  • Rustのクレートは crates.io を通じて簡単に導入・管理できる
  • tokioserdeclap はRust開発の三本柱とも言える人気クレート
  • クレートをうまく活用すれば、少ないコードで高機能なアプリケーションが作れる
  • 他にも anyhowthiserrorchrono など実用的なクレートが多数存在する

次は、これらのツールを使って 実際の小規模プロジェクトをどう構成・運用していくか を見ていきましょう。

Rustの実プロジェクト構築

Rustで本格的な開発を進めるうえで重要になるのが、プロジェクトの構成設計継続的な開発・運用体制(CI/CD) の整備です。
これまで学んできた文法やライブラリは、あくまで「道具」にすぎません。
それらを活かして、継続的に保守・拡張しやすいプロジェクト構造を設計し、チーム開発や自動化にも対応できる形へと昇華させる ことが求められます。

この章では、小規模プロジェクトを設計する際のベストプラクティス と、GitHub Actionsなどを使ったCI/CD環境の構築方法 を解説します。
「動くコード」から「管理されるコード」へ。
Rustを“仕事道具”として使いこなす準備をここで整えましょう。

小規模プロジェクトの設計

プロジェクトの基本構成

Rustプロジェクトでは、基本的に以下のようなディレクトリ構成が一般的です。

my_project/
├── Cargo.toml
├── src/
│   ├── main.rs
│   ├── lib.rs
│   ├── config.rs
│   └── handlers/
│       └── user.rs
├── tests/
│   └── integration_test.rs
├── README.md
└── .github/
    └── workflows/
        └── ci.yml
ディレクトリ / ファイル役割
main.rsアプリのエントリーポイント
lib.rs共通モジュールのまとめ(再利用やテスト向け)
config.rs設定管理用モジュール
handlers/機能単位でファイルを分離する(ドメイン駆動風)
tests/統合テストのためのディレクトリ
.github/workflows/GitHub ActionsによるCI/CD設定

設計のポイント

  • main.rs は最低限にし、ロジックは lib.rs に分離
  • 関心の分離(Separation of Concerns)を意識してモジュールを構成
  • 依存注入のような設計パターンを導入し、テスト容易性を確保する
  • 外部クレートの使用は明示的なラッパー関数にまとめておくと差し替えが容易

このような構成にしておくことで、機能の追加や修正がしやすくなり、コードの再利用やテストも効率的に行えるようになります。

CI/CDの設定

CI/CDとは?

CI(継続的インテグレーション)とCD(継続的デリバリー/デプロイ)は、開発の自動化を通じて
品質の担保と迅速なリリースを両立させる開発フロー のことです。

Rustでは、GitHub Actionsを使ってテストやビルドを自動で実行するワークフロー を簡単に設定できます。

GitHub Actions の設定例

以下は、Push時に自動で cargo test を実行する基本的な設定です。

# .github/workflows/ci.yml
name: Rust CI

on:
  push:
    branches: [ main ]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Rustのセットアップ
      uses: actions/setup-rust@v1
      with:
        rust-version: stable

    - name: 依存の取得とビルド
      run: cargo build --verbose

    - name: テスト実行
      run: cargo test --all

拡張アイデア

  • cargo clippycargo fmt -- --check を追加して静的解析やフォーマットチェック
  • cargo tarpaulin などを使ってカバレッジ測定(Linuxのみ対応)
  • 本番リリース用に docker build やデプロイ処理も組み込む

CI/CDの導入により、コードの信頼性が継続的に保たれる だけでなく、チーム開発においてもレビュー精度や生産性を向上させる効果 があります。

まとめ

  • 小規模Rustプロジェクトでは、src/lib.rs を中心にモジュール化する設計が有効
  • ディレクトリ構成を整えておくと、後々の保守・テスト・拡張がしやすくなる
  • GitHub Actions を使えば、簡単に CI/CD を導入できる
  • ビルド・テスト・フォーマットチェックを自動化して、安定した開発体制を実現できる

これで 第8回「エコシステム活用」 は完了です。
次回の 第9回では、Rustにおけるオブジェクト指向的設計やポインタ・参照の高度な活用方法 を学び、Rustの柔軟性と表現力をさらに引き出していきます。

  • この記事を書いた人

ふくまる

機械設計業をしていたが25歳でエンジニアになると決意して行動開始→ 26歳でエンジニアに転職→ 28歳でフリーランスエンジニアに→ 現在、34歳でフリーランス7年目 Go案件を受注中 Go,GCPが得意分野

-Rust, プログラミング, 入門