
روز ۴۷: ساخت یک CLI Tool واقعی با Rust
برنامههای خط فرمان (CLI) بخش مهمی از ابزارهای توسعهدهندگان و مدیران سیستم هستند. این ابزارها برای پردازش دادهها، مدیریت فایلها، اجرای وظایف خودکار و ایجاد workflowهای سریع استفاده میشوند. Rust به دلیل کارایی بالا، ایمنی حافظه و مدیریت دقیق خطا، گزینهای ایدهآل برای ساخت CLI Toolهاست. استفاده از Cargo، Crateهای موجود و سیستم مدیریت وابستگیها، توسعه CLI را سریع و قابل نگهداری میکند. در این مقاله، به صورت گامبهگام یاد میگیریم چگونه یک CLI Tool واقعی با Rust بسازیم که شامل پارس کردن آرگومانها، خواندن و نوشتن فایلها و مدیریت خطاها باشد.
ایجاد پروژه و نصب Crateهای مورد نیاز
ابتدا باید یک پروژه Rust جدید بسازیم. با دستور زیر میتوان پروژه را ایجاد کرد:
cargo new cli_tool --bin cd cli_tool
برای ساخت یک CLI حرفهای، معمولاً از Crateهای موجود مانند clap برای پارس کردن آرگومانها و serde برای پردازش دادههای JSON استفاده میکنیم. در Cargo.toml، وابستگیها به شکل زیر اضافه میشوند:
[dependencies]
clap = { version = "4.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"این کار باعث میشود ابزار ما قابلیت دریافت پارامترهای خط فرمان، خواندن فایلهای JSON و مدیریت دادهها را بهسادگی داشته باشد.
پارس کردن آرگومانهای خط فرمان با Clap
Crate clap به ما اجازه میدهد پارامترها و flagهای خط فرمان را تعریف کنیم و به صورت ایمن آنها را دریافت کنیم. مثال زیر ساختار اولیه CLI را نشان میدهد:
use clap::Parser;
#[derive(Parser)]
#[command(name = "cli_tool", version = "1.0", author = "Your Name")]
struct Cli {
#[arg(short, long)]
input: String,
#[arg(short, long, default_value = "output.json")]
output: String,
}
fn main() {
let args = Cli::parse();
println!("Input file: {}", args.input);
println!("Output file: {}", args.output);
}
در این مثال، دو آرگومان خط فرمان تعریف کردیم: input برای فایل ورودی و output برای فایل خروجی با مقدار پیشفرض. با استفاده از Cli::parse()، پارامترها خوانده میشوند و مطمئن میشویم که کاربر ورودیهای مورد نیاز را ارائه کرده است.
خواندن و پردازش فایلها
پس از پارس کردن آرگومانها، معمولاً لازم است دادهها را از فایلها بخوانیم و پردازش کنیم. Rust با توابع ایمن I/O و مدیریت خطا این کار را به راحتی انجام میدهد:
use std::fs;
use std::io;
fn read_input(file_path: &str) -> io::Result<String> {
let content = fs::read_to_string(file_path)?;
Ok(content)
}
این تابع محتوای فایل ورودی را خوانده و خطاهای احتمالی را به صورت ایمن مدیریت میکند. Rust با سیستم Result تضمین میکند که هیچ خطای I/O نادیده گرفته نشود و برنامه ایمن باقی بماند.
پردازش دادهها و JSON
یکی از کاربردهای رایج CLI Toolها پردازش دادههای ساختاریافته مانند JSON است. با استفاده از serde و serde_json میتوان دادهها را به صورت امن Deserialize و Serialize کرد:
use serde::{Serialize, Deserialize};
use serde_json;
#[derive(Serialize, Deserialize)]
struct Record {
name: String,
age: u32,
}
fn process_data(content: &str) -> Vec<Record> {
serde_json::from_str(content).unwrap_or_else(|_| vec![])
}در اینجا دادهها از JSON به Structهای Rust تبدیل میشوند. سیستم نوع Rust باعث میشود اطمینان داشته باشیم که دادهها درست پردازش شدهاند و خطاهای زمان اجرا کاهش پیدا میکند.
نوشتن خروجی به فایل
پس از پردازش دادهها، معمولاً میخواهیم خروجی را ذخیره کنیم. استفاده از serde_json::to_string_pretty و I/O ایمن Rust این کار را آسان میکند:
fn write_output(records: &Vec<Record>, file_path: &str) -> io::Result<()> {
let json = serde_json::to_string_pretty(records)?;
fs::write(file_path, json)?;
Ok(())
}این روش باعث میشود خروجی خوانا و مرتب باشد و خطاها در طول نوشتن فایل مدیریت شوند.
اجرای CLI Tool
با ترکیب تمام بخشها، میتوان CLI Tool نهایی را اجرا کرد:
fn main() -> io::Result<()> {
let args = Cli::parse();
let content = read_input(&args.input)?;
let records = process_data(&content);
write_output(&records, &args.output)?;
println!("Processed {} records!", records.len());
Ok(())
}این ابزار ساده فایل JSON ورودی را خوانده، دادهها را پردازش کرده و در فایل خروجی ذخیره میکند. میتوان با افزودن flagها و گزینههای بیشتر، قابلیتهای بیشتری به آن اضافه کرد.
نکات مهم در طراحی CLI
مدیریت خطاها: استفاده از
Resultو?برای اطمینان از ایمنی برنامهخوانایی و ساختار: تقسیم کد به توابع کوچک و واضح
استفاده از Crateها: بهرهگیری از
clap،serdeو دیگر کتابخانهها برای کاهش پیچیدگیتست و مثال عملی: تست CLI با فایلهای نمونه و بررسی edge caseها
CLI Toolها در Rust به دلیل ایمنی حافظه، کارایی بالا و مدیریت دقیق خطا، برای ابزارهای توسعهدهنده و مدیریت سیستم مناسب هستند. یادگیری ساخت چنین ابزارهایی باعث میشود توسعهدهنده بتواند برنامههای مقیاسپذیر، ایمن و قابل نگهداری بسازد.