Rust CLI Development
Building powerful command-line applications with Rust
⚡ Rust CLI Applications
Rust excels at building fast, reliable command-line tools. With excellent argument parsing, error handling, and cross-platform support, Rust makes CLI development efficient and robust.
// Simple CLI application
use std::env;
fn main() {
let args: Vec = env::args().collect();
println!("Hello, {}!", args.get(1).unwrap_or(&"World".to_string()));
}
Usage:
./my_cli Alice
→ "Hello, Alice!"
Essential CLI Crates
Clap
Command line argument parser
use clap::Parser;
#[derive(Parser)]
struct Args {
name: String,
}
Colored
Add colors to terminal output
use colored::*;
println!("{}", "Success!".green());
println!("{}", "Error!".red());
Indicatif
Progress bars and spinners
let bar = ProgressBar::new(100);
for i in 0..100 {
bar.inc(1);
}
Dialoguer
Interactive prompts and menus
let name: String = Input::new()
.with_prompt("Your name")
.interact()?;
🔹 Basic CLI with Clap
Create a professional CLI application:
# Cargo.toml
[dependencies]
clap = { version = "4.0", features = ["derive"] }
colored = "2.0"
// main.rs
use clap::{Parser, Subcommand};
use colored::*;
#[derive(Parser)]
#[command(name = "mytool")]
#[command(about = "A simple CLI tool", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Option,
}
#[derive(Subcommand)]
enum Commands {
/// Greet someone
Greet {
/// Name of the person to greet
#[arg(short, long)]
name: String,
/// Number of times to greet
#[arg(short, long, default_value_t = 1)]
count: u8,
},
/// Show version information
Version,
}
fn main() {
let cli = Cli::parse();
match &cli.command {
Some(Commands::Greet { name, count }) => {
for _ in 0..*count {
println!("{} {}!", "Hello".green().bold(), name.cyan());
}
}
Some(Commands::Version) => {
println!("{} {}", "mytool".bold(), "v1.0.0".dimmed());
}
None => {
println!("{}", "Use --help for usage information".yellow());
}
}
}
Usage Examples:
-
mytool greet --name Alice -
mytool greet -n Bob -c 3 -
mytool version
🔹 File Processing CLI
Build a tool that processes files:
use clap::Parser;
use std::fs;
use std::path::PathBuf;
use colored::*;
#[derive(Parser)]
struct Args {
/// Input file to process
#[arg(short, long)]
input: PathBuf,
/// Output file (optional)
#[arg(short, long)]
output: Option,
/// Convert to uppercase
#[arg(long)]
uppercase: bool,
/// Count lines
#[arg(long)]
count_lines: bool,
}
fn main() -> Result<(), Box> {
let args = Args::parse();
// Read input file
let content = fs::read_to_string(&args.input)?;
println!("{} Reading file: {}", "✓".green(), args.input.display());
let mut result = content;
// Process content
if args.uppercase {
result = result.to_uppercase();
println!("{} Converted to uppercase", "✓".green());
}
if args.count_lines {
let line_count = result.lines().count();
println!("{} Line count: {}", "ℹ".blue(), line_count.to_string().bold());
}
// Write output
match args.output {
Some(output_path) => {
fs::write(&output_path, result)?;
println!("{} Written to: {}", "✓".green(), output_path.display());
}
None => {
println!("\n{}", "Output:".bold());
println!("{}", result);
}
}
Ok(())
}
Usage:
mytool -i input.txt -o output.txt --uppercase --count-lines
🔹 Interactive CLI with Progress
Create an interactive CLI with progress indicators:
# Add to Cargo.toml
indicatif = "0.17"
dialoguer = "0.10"
tokio = { version = "1.0", features = ["full"] }
use dialoguer::{Input, Select, Confirm};
use indicatif::{ProgressBar, ProgressStyle};
use std::time::Duration;
use tokio::time::sleep;
#[tokio::main]
async fn main() -> Result<(), Box> {
println!("{}", "🚀 Welcome to Interactive CLI".bold().cyan());
// Get user input
let name: String = Input::new()
.with_prompt("What's your name?")
.interact()?;
// Show selection menu
let selections = &["Process files", "Download data", "Generate report"];
let selection = Select::new()
.with_prompt("What would you like to do?")
.default(0)
.items(&selections[..])
.interact()?;
// Confirm action
let confirmed = Confirm::new()
.with_prompt(format!("Hello {}! Proceed with '{}'?", name, selections[selection]))
.interact()?;
if confirmed {
// Show progress bar
let pb = ProgressBar::new(100);
pb.set_style(ProgressStyle::default_bar()
.template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos:>7}/{len:7} {msg}")
.unwrap()
.progress_chars("##-"));
for i in 0..100 {
pb.set_message(format!("Processing item {}", i + 1));
pb.inc(1);
sleep(Duration::from_millis(50)).await;
}
pb.finish_with_message("✅ Task completed successfully!");
println!("{} Thanks for using our CLI, {}!", "🎉".bold(), name.green());
} else {
println!("{}", "Operation cancelled.".yellow());
}
Ok(())
}
Features:
- Interactive prompts
- Selection menus
- Progress bars
- Colored output