Rust

روز ۴۷: ساخت یک 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 به دلیل ایمنی حافظه، کارایی بالا و مدیریت دقیق خطا، برای ابزارهای توسعه‌دهنده و مدیریت سیستم مناسب هستند. یادگیری ساخت چنین ابزارهایی باعث می‌شود توسعه‌دهنده بتواند برنامه‌های مقیاس‌پذیر، ایمن و قابل نگهداری بسازد.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

یازده + نوزده =

دکمه بازگشت به بالا