Rust
Introducing clap
Learn CLI basics with the clap crate.
What clap is
clap is Rust's most common command-line argument parser. You define a struct; clap reads the arguments, converts them to their types, and produces clear errors for missing or invalid input plus an automatic --help:
// Cargo.toml: clap = { version = "4", features = ["derive"] }
use clap::Parser;
#[derive(Parser)]
struct Args {
#[arg(long)]
ad: String,
}
fn main() {
let args = Args::parse();
println!("Merhaba {}", args.ad);
}
// $ selam --ad Ece → Merhaba Ece
Since there are no external crates in the exercise environment, we'll write by hand what clap does behind the scenes; this also shows how much work the library saves.
Parsing by hand
To find a flag's value, the name is searched among the arguments and the next element is taken:
struct Args {
ad: String,
}
fn ayristir(args: &[&str]) -> Result<Args, String> {
let i = args.iter().position(|a| *a == "--ad").ok_or("--ad gerekli")?;
let ad = args.get(i + 1).ok_or("--ad için değer eksik")?;
Ok(Args { ad: ad.to_string() })
}
ok_or turns an Option into a Result with an error message.
Exercise Read a flag
Write the Args and ayristir code above. Print Merhaba Ece for ["selam", "--ad", "Ece"] and the error message as hata: ... for ["selam"].
Show example solution
struct Args {
ad: String,
}
fn ayristir(args: &[&str]) -> Result<Args, String> {
let i = args.iter().position(|a| *a == "--ad").ok_or("--ad gerekli")?;
let ad = args.get(i + 1).ok_or("--ad için değer eksik")?;
Ok(Args { ad: ad.to_string() })
}
fn main() {
for girdi in [vec!["selam", "--ad", "Ece"], vec!["selam"]] {
match ayristir(&girdi) {
Ok(a) => println!("Merhaba {}", a.ad),
Err(e) => println!("hata: {}", e),
}
}
}
Test yourself
-
What does <code>Args::parse()</code> do if the required <code>--ad</code> isn't given?
- Returns None
- Prints an error message and usage, then exits the program
- Uses an empty string
- Panics
Show answer
Prints an error message and usage, then exits the program — parse exits on error; if you want to handle the error yourself, try_parse returns a Result.
-
Parser trait
#[derive(____)]
struct Args {
#[arg(long)]
ad: String,
}
Show answer
#[derive(Parser)]
struct Args {
#[arg(long)]
ad: String,
}
-
Command line and result
- selam --ad Ece
- Merhaba Ece
- selam
- Error: --ad required
- selam --ad
- Error: value missing
- selam --help
- Automatic help
Next lesson: Derive macro