Derive macro
- Rust course
- Intermediate
- Lesson 96/115
- 4 min
Define an argument struct with #[derive(Parser)].
The derive macro
In clap, struct fields become arguments; doc comments (///) become help text and attributes decide behaviour:
/// Kullanıcıyı selamlar
#[derive(Parser)]
#[command(version, about)]
struct Args {
/// Selamlanacak kişi
#[arg(short, long)]
ad: String,
/// Kaç kez selamlanacak
#[arg(short, long, default_value_t = 1)]
tekrar: u32,
}short → -a, long → --ad. The field type decides the conversion: if it's u32, an input like "abc" errors automatically.
Defaults and conversion by hand
To build the same behaviour by hand, a helper can be written for each flag:
fn deger<'a>(args: &[&'a str], ad: &str) -> Option<&'a str> {
let i = args.iter().position(|a| *a == ad)?;
args.get(i + 1).copied()
}
let tekrar: u32 = match deger(args, "--tekrar") {
Some(s) => s.parse().map_err(|_| format!("--tekrar sayı olmalı: {s}"))?,
None => 1,
};Practice Repeated greeting
Parse Args { ad: String, tekrar: u32 } with the deger helper above; if --tekrar is missing, let it be 1. For ["--ad", "Ece", "--tekrar", "3"], print the line Merhaba Ece tekrar times.
Starter code
fn main() {
// buraya yaz
}Sample solution
struct Args {
ad: String,
tekrar: u32,
}
fn deger<'a>(args: &[&'a str], ad: &str) -> Option<&'a str> {
let i = args.iter().position(|a| *a == ad)?;
args.get(i + 1).copied()
}
fn ayristir(args: &[&str]) -> Result<Args, String> {
let ad = deger(args, "--ad").ok_or("--ad gerekli")?.to_string();
let tekrar: u32 = match deger(args, "--tekrar") {
Some(s) => s.parse().map_err(|_| format!("--tekrar sayı olmalı: {s}"))?,
None => 1,
};
Ok(Args { ad, tekrar })
}
fn main() {
let a = ayristir(&["--ad", "Ece", "--tekrar", "3"]).unwrap();
for _ in 0..a.tekrar {
println!("Merhaba {}", a.ad);
}
}Expected output
Merhaba Ece Merhaba Ece Merhaba Ece
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What does <code>#[arg(default_value_t = 1)]</code> provide?
- If the flag isn't given, the field is 1 and the argument becomes optional Correct answer
- The value is always 1
- It must be at least 1
- Writes 1 in the help text
Explanation: The default value is also shown in the help output: [default: 1].
2 Long and short name
#[arg(short, ____)]
ad: String,
#[arg(short, long)]
ad: String,
Explanation: long produces the --ad flag from the field name.
3 Attribute and effect
| Term | Meaning |
|---|---|
#[arg(short)] |
-a |
#[arg(long)] |
--ad |
default_value_t = 1 |
Default 1 |
/// description |
Help text |