إطار عمل CLI لـ Rust: إنشاء تطبيقات وحدة تحكم قوية
Rust هي لغة برمجة نظامية مثالية لإنشاء أدوات وحدة تحكم سريعة وموثوقة. بفضل الكتابة الصارمة، والتجريدات ذات التكلفة الصفرية، ومدير الحزم المدمج Cargo، تتيح Rust تطوير أدوات CLI تعمل فورًا ولا تتطلب مترجمًا فوريًا. في هذه المقالة، سنستعرض ثلاثة أطر عمل CLI شائعة لـ Rust: clap، structopt، و argh، وسنوضح كيفية استخدامها لإنشاء تطبيقات وحدة تحكم احترافية.
لماذا Rust لواجهات CLI؟
يتم اختيار Rust لتطوير CLI لعدة أسباب:
- الأداء — يعمل الكود المترجم بمستوى C/C++.
- أمان الذاكرة — نظام الملكية يمنع تسرب البيانات وسباقات البيانات.
- التوافق عبر المنصات — قاعدة كود واحدة تعمل على Windows وmacOS وLinux.
- النظام البيئي — آلاف الحزم الجاهزة (crates) لأي مهمة.
1. Clap — معيار الصناعة
clap (Command Line Argument Parser) هو إطار العمل الأكثر شيوعًا لتحليل وسائط سطر الأوامر في Rust. وهو يدعم الوسائط الموضعية، والخيارات، والأعلام، والأوامر الفرعية، والتوليد التلقائي للمساعدة، والإكمال التلقائي لـ Bash/Zsh/Fish.
التثبيت
أضف إلى Cargo.toml:
[dependencies]clap = { version = "4.5", features = ["derive"] }مثال: آلة حاسبة بسيطة
use clap::Parser;
#[derive(Parser)]#[command(name = "calc")]#[command(about = "آلة حاسبة CLI بسيطة")]struct Cli { /// الرقم الأول a: f64,
/// الرقم الثاني b: f64,
/// العملية: add, sub, mul, div #[arg(short, long, default_value = "add")] operation: String,}
fn main() { let cli = Cli::parse(); let result = match cli.operation.as_str() { "add" => cli.a + cli.b, "sub" => cli.a - cli.b, "mul" => cli.a * cli.b, "div" => { if cli.b == 0.0 { eprintln!("خطأ: القسمة على صفر"); std::process::exit(1); } cli.a / cli.b } _ => { eprintln!("عملية غير معروفة: {}", cli.operation); std::process::exit(1); } }; println!("النتيجة: {}", result);}التشغيل:
cargo run -- 10 5 --operation mul# الإخراج: النتيجة: 502. Structopt — نهج أنيق
structopt كان سابقًا حزمة منفصلة، ولكن وظائفها مدمجة الآن في clap عبر وحدات الماكرو المشتقة. ومع ذلك، لا تزال العديد من المشاريع القديمة تستخدمه مباشرة. يتيح Structopt وصف الوسائط كحقول هيكل مع تعليقات توضيحية.
التثبيت (للمشاريع القديمة)
[dependencies]structopt = "0.3"مثال: أداة للعمل مع الملفات
use structopt::StructOpt;use std::path::PathBuf;
#[derive(StructOpt)]#[structopt(name = "fileutil", about = "أداة للعمل مع الملفات")]struct Opt { /// ملف الإدخال #[structopt(parse(from_os_str))] input: PathBuf,
/// ملف الإخراج (اختياري) #[structopt(parse(from_os_str), short = "o", long = "output")] output: Option<PathBuf>,
/// الوضع: copy أو move #[structopt(short, long, default_value = "copy")] mode: String,
/// علم verbose #[structopt(short, long)] verbose: bool,}
fn main() { let opt = Opt::from_args(); if opt.verbose { println!("جارٍ معالجة الملف: {:?}", opt.input); } // منطق النسخ/النقل}3. Argh — البساطة والسرعة
argh هو إطار عمل خفيف مع حد أدنى من التبعيات