Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

クレートエコシステム

Rustの豊富なライブラリ(クレート)を活用する方法を学びます。

crates.io

crates.io はRustの公式パッケージレジストリです。

クレートを探す

  1. crates.ioで検索
  2. lib.rs で分類別に探す
  3. GitHubのAwesome Rustリストを参照

良いクレートの選び方

指標確認ポイント
ダウンロード数多いほど信頼性が高い傾向
最終更新活発にメンテナンスされているか
ドキュメントdocs.rsで確認
依存関係少ないほどシンプル
ライセンスMIT/Apache 2.0が一般的

主要クレート紹介

シリアライゼーション: serde

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
use serde::{Deserialize, Serialize};

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

fn main() {
    let user = User {
        name: String::from("太郎"),
        age: 25,
    };

    // JSON化
    let json = serde_json::to_string(&user).unwrap();
    println!("{}", json);

    // JSONからパース
    let parsed: User = serde_json::from_str(&json).unwrap();
    println!("{:?}", parsed);
}

HTTPクライアント: reqwest

[dependencies]
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
use reqwest;

#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
    let body = reqwest::get("https://httpbin.org/get")
        .await?
        .text()
        .await?;

    println!("{}", body);
    Ok(())
}

非同期ランタイム: tokio

[dependencies]
tokio = { version = "1", features = ["full"] }
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
    println!("開始");
    sleep(Duration::from_secs(1)).await;
    println!("1秒後");
}

CLI引数パース: clap

[dependencies]
clap = { version = "4", features = ["derive"] }
use clap::Parser;

#[derive(Parser, Debug)]
#[command(name = "myapp")]
#[command(about = "サンプルアプリケーション")]
struct Args {
    /// 名前
    #[arg(short, long)]
    name: String,

    /// 回数
    #[arg(short, long, default_value_t = 1)]
    count: u8,
}

fn main() {
    let args = Args::parse();

    for _ in 0..args.count {
        println!("Hello, {}!", args.name);
    }
}

ログ: tracing

[dependencies]
tracing = "0.1"
tracing-subscriber = "0.3"
use tracing::{info, warn, error, debug};
use tracing_subscriber;

fn main() {
    tracing_subscriber::fmt::init();

    info!("アプリケーション開始");
    debug!("デバッグ情報");
    warn!("警告");
    error!("エラー");
}

日時: chrono

[dependencies]
chrono = "0.4"
use chrono::{Local, Utc};

fn main() {
    let now = Local::now();
    println!("現在時刻: {}", now.format("%Y-%m-%d %H:%M:%S"));

    let utc = Utc::now();
    println!("UTC: {}", utc);
}

正規表現: regex

[dependencies]
regex = "1"
use regex::Regex;

fn main() {
    let re = Regex::new(r"\d{3}-\d{4}").unwrap();
    let text = "郵便番号: 123-4567";

    if let Some(m) = re.find(text) {
        println!("見つかりました: {}", m.as_str());
    }
}

カテゴリ別おすすめクレート

Web開発

クレート用途
axumWebフレームワーク
actix-web高性能Webフレームワーク
towerミドルウェア

データベース

クレート用途
sqlx非同期SQL
dieselORM
sea-orm非同期ORM

エラー処理

クレート用途
thiserrorカスタムエラー定義
anyhow柔軟なエラー処理

テスト

クレート用途
mockallモック
proptestプロパティベーステスト

まとめ

カテゴリ推奨クレート
シリアライズserde + serde_json
HTTPreqwest
非同期tokio
CLIclap
ログtracing
日時chrono
正規表現regex

確認テスト

Q1. serdeの主な用途は?

Q2. tokioの役割は?

Q3. `#[derive(Serialize, Deserialize)]`を構造体に付けると何ができる?

Q4. `#[derive(Serialize, Deserialize)]`を使うために必要なCargo.tomlの設定は?

Q5. chronoクレートで現在時刻を"2024-01-15 10:30:00"形式で表示するフォーマット文字列は?


次のドキュメント: 03_testing.md