systems-programming-rust-project について
バイナリ、ライブラリ、ワークスペース、Web API、WebAssembly向けのRustプロジェクト構成を支援するスキルです。Cargoの構成、設定、テスト、開発ツールを案内し、バージョンやセキュリティ境界の確認、実際のビルド検証を重視します。
主な機能
- 01プロジェクト種別の分析と構成選択
- 02Cargoプロジェクトの構成案
- 03設定、モジュール、エラー処理の設計
- 04テスト、文書、開発ツールの準備
- 05ツールチェーン確認とビルド検証の重視
活用シーン
- 01Rustバイナリプロジェクトの初期設計
- 02Rustライブラリや複数クレートのワークスペース構築
- 03Axum Web APIのプロジェクト構成設計
- 04テストとフォーマット確認の設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill systems-programming-rust-projectインストール後、Claude Code で/systems-programming-rust-projectを入力して読み込まれたか確認します。
詳細
Rust プロジェクトのスキャフォールディング
Rust アプリケーションの本番運用に適したスキャフォールディングを専門とする、Rust プロジェクトアーキテクチャのエキスパートです。Rust のベストプラクティスに沿って、Cargo ツール、適切なモジュール構成、テスト環境、設定を備えた完全なプロジェクト構造を生成します。
このスキルを使用する場面
- Rust プロジェクトのスキャフォールディングに関するタスクやワークフローに取り組む場合
- Rust プロジェクトのスキャフォールディングに関するガイダンス、ベストプラクティス、チェックリストが必要な場合
このスキルを使用しない場面
- タスクが Rust プロジェクトのスキャフォールディングと無関係な場合
- この範囲外の別のドメインやツールが必要な場合
コンテキスト
ユーザーは、適切な構成、依存関係管理、テスト、ビルド設定を備えた、慣用的で安全かつ高性能なアプリケーションを作成する自動 Rust プロジェクトスキャフォールディングを必要としています。Rust の慣用的な書き方とスケーラブルなアーキテクチャを重視してください。
要件
$ARGUMENTS
指示
空のディレクトリ、または承認済みのディレクトリでスキャフォールドを1つ選択してください。これらの断片にはコマンドモジュール、CoreType、エラー実装、テストが含まれていないため、コンパイル可能なプロジェクトとして完成させるには、それらのファイルを実装し、完了とする前に cargo fmt、cargo check、cargo clippy、cargo test を実行してください。サポート対象のツールチェーンと依存関係のセットを固定し、宣言した MSRV を検証してください。semver の範囲指定では、より新しい依存関係が解決されることがあります。プレースホルダーの権利表記をコピーせず、実際の作者とライセンスを指定してください。保護対象の API ルートには認証/認可を追加し、ネットワークリスナーは意図した場合にのみ公開してください。
1. プロジェクトの種類を分析する
ユーザーの要件に基づいて、プロジェクトの種類を判断します。
- バイナリ:CLI ツール、アプリケーション、サービス
- ライブラリ:再利用可能なクレート、共有ユーティリティ
- ワークスペース:複数クレートのプロジェクト、モノレポ
- Web API:Actix/Axum の Web サービス、REST API
- WebAssembly:ブラウザベースのアプリケーション
2. Cargo でプロジェクトを初期化する
# Create binary project
cargo new project-name
cd project-name
# Or create library
cargo new --lib library-name
# Initialize git (cargo does this automatically)
# Add to .gitignore if needed
echo "/target" >> .gitignore
# Decide Cargo.lock policy explicitly; libraries may commit it for reproducible CI.
# Downstream library consumers resolve their own lockfiles.
3. バイナリプロジェクトの構造を生成する
binary-project/
├── Cargo.toml
├── README.md
├── src/
│ ├── main.rs
│ ├── config.rs
│ ├── cli.rs
│ ├── commands/
│ │ ├── mod.rs
│ │ ├── init.rs
│ │ └── run.rs
│ ├── error.rs
│ └── lib.rs
├── tests/
│ ├── integration_test.rs
│ └── common/
│ └── mod.rs
├── benches/
│ └── benchmark.rs
└── examples/
└── basic_usage.rs
Cargo.toml:
[package]
name = "project-name"
version = "0.1.0"
edition = "2021"
rust-version = "1.75"
authors = ["Your Name <[email protected]>"]
description = "Project description"
license = "MIT OR Apache-2.0"
repository = "https://github.com/user/project-name"
[dependencies]
clap = { version = "4.5", features = ["derive"] }
tokio = { version = "1.36", features = ["full"] }
anyhow = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[dev-dependencies]
criterion = "0.5"
[[bench]]
name = "benchmark"
harness = false
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
src/main.rs:
use anyhow::Result;
use clap::Parser;
mod cli;
mod commands;
mod config;
mod error;
use cli::Cli;
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
match cli.command {
cli::Commands::Init(args) => commands::init::execute(args).await?,
cli::Commands::Run(args) => commands::run::execute(args).await?,
}
Ok(())
}
src/cli.rs:
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "project-name")]
#[command(about = "Project description", long_about = None)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
/// Initialize a new project
Init(InitArgs),
/// Run the application
Run(RunArgs),
}
#[derive(Parser)]
pub struct InitArgs {
/// Project name
#[arg(short, long)]
pub name: String,
}
#[derive(Parser)]
pub struct RunArgs {
/// Enable verbose output
#[arg(short, long)]
pub verbose: bool,
}
src/error.rs:
use std::fmt;
#[derive(Debug)]
pub enum AppError {
NotFound(String),
InvalidInput(String),
IoError(std::io::Error),
}
impl fmt::Display for AppError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AppError::NotFound(msg) => write!(f, "Not found: {}", msg),
AppError::InvalidInput(msg) => write!(f, "Invalid input: {}", msg),
AppError::IoError(e) => write!(f, "IO error: {}", e),
}
}
}
impl std::error::Error for AppError {}
pub type Result<T> = std::result::Result<T, AppError>;
4. ライブラリプロジェクトの構造を生成する
library-name/
├── Cargo.toml
├── README.md
├── src/
│ ├── lib.rs
│ ├── core.rs
│ ├── utils.rs
│ └── error.rs
├── tests/
│ └── integration_test.rs
└── examples/
└── basic.rs
ライブラリ用 Cargo.toml:
[package]
name = "library-name"
version = "0.1.0"
edition = "2021"
rust-version = "1.75"
[dependencies]
# Keep minimal for libraries
[dev-dependencies]
tokio-test = "0.4"
[lib]
name = "library_name"
path = "src/lib.rs"
src/lib.rs:
//! Library documentation
//!
//! # Examples
//!
//! ```
//! use library_name::core::CoreType;
//!
//! let instance = CoreType::new();
//! ```
pub mod core;
pub mod error;
pub mod utils;
pub use core::CoreType;
pub use error::{Error, Result};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
5. ワークスペースの構造を生成する
workspace/
├── Cargo.toml
├── .gitignore
├── crates/
│ ├── api/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ ├── core/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ └── cli/
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
└── tests/
└── integration_test.rs
Cargo.toml(ワークスペースのルート):
[workspace]
members = [
"crates/api",
"crates/core",
"crates/cli",
]
resolver = "2"
[workspace.package]
version = "0.1.0"
edition = "2021"
rust-version = "1.75"
authors = ["Your Name <[email protected]>"]
license = "MIT OR Apache-2.0"
[workspace.dependencies]
tokio = { version = "1.36", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
[profile.release]
opt-level = 3
lto = true
6. Web API の構造を生成する(Axum)
web-api/
├── Cargo.toml
├── src/
│ ├── main.rs
│ ├── routes/
│ │ ├── mod.rs
│ │ ├── users.rs
│ │ └── health.rs
│ ├── handlers/
│ │ ├── mod.rs
│ │ └── user_handler.rs
│ ├── models/
│ │ ├── mod.rs
│ │ └── user.rs
│ ├── services/
│ │ ├── mod.rs
│ │ └── user_service.rs
│ ├── middleware/
│ │ ├── mod.rs
│ │ └── auth.rs
│ └── error.rs
└── tests/
└── api_tests.rs
Web API 用 Cargo.toml:
[package]
name = "web-api"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.7"
tokio = { version = "1.36", features = ["full"] }
tower = "0.4"
tower-http = { version = "0.5", features = ["trace", "cors"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
sqlx = { version = "0.7", features = ["runtime-tokio-native-tls", "postgres"] }
tracing = "0.1"
tracing-subscriber = "0.3"
src/main.rs(Axum):
use axum::{Router, routing::get};
use tower_http::cors::CorsLayer;
use std::net::SocketAddr;
mod routes;
mod handlers;
mod models;
mod services;
mod error;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let app = Router::new()
.route("/health", get(routes::health::health_check))
.nest("/api/users", routes::users::router())
.layer(CorsLayer::new()); // add only approved origins/methods if cross-origin access is needed
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
tracing::info!("Listening on {}", addr);
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app).await.unwrap();
}
7. 開発ツールを設定する
Makefile:
.PHONY: build test lint fmt run clean bench
build:
cargo build
test:
cargo test
lint:
cargo clippy -- -D warnings
fmt:
cargo fmt --check
run:
cargo run
clean:
cargo clean
bench:
cargo bench
rustfmt.toml:
edition = "2021"
max_width = 100
tab_spaces = 4
use_small_heuristics = "Max"
clippy.toml:
cognitive-complexity-threshold = 30
出力形式
- プロジェクト構造:Rust の慣用的な構成に沿った、完全なディレクトリツリー
- 設定:依存関係とビルド設定を含む Cargo.toml
- エントリーポイント:適切なドキュメントを備えた main.rs または lib.rs
- テスト:単体テストと統合テストの構成
- ドキュメント:README とコードドキュメント
- 開発ツール:Makefile、clippy/rustfmt の設定
型安全性、適切なエラー処理、包括的なテスト環境を備えた、慣用的な Rust プロジェクトの作成に重点を置いてください。
制限事項
- このスキルは、タスクが上記の範囲に明確に該当する場合にのみ使用してください。
- 出力を、環境固有の検証、テスト、専門家によるレビューの代わりとして扱わないでください。
- 必要な入力、権限、安全上の境界、成功基準が不足している場合は、作業を中断して確認を求めてください。