Clap, Rust CLI
About CLAP
Clap står for Comand Line Argument Parser og er ett crate for å parse og validere strenger fra kommandolinjeargumenter.
Hvorfor gjør jeg dette ?
Jeg er veldig glad i Go-lang sine Cobra og Viper moduler og CLI verktøyet som følger med, genialt for å lage CLI verktøy. Mitt problem er, at jeg skriver all annen software i Rust og den context switchen for å kode Go-lang igjen, stjeler for mye tid.
Cargo integrasjon
Jeg kan bruke cargo my-command --args
slik at jeg integerer med cargo.
Komme i gang med CLAP
Jeg tar utgangspunkt i at du allerede har skapt ett cargo prosjekt for CLI applikasjonen din.
Legg til clap til Cargo.toml cargo add clap -F derive
hvor -F flagget står for feature.
Din cargo.toml fil bør da inneholde noe som dette:
[dependencies]
clap = { version = "4.1.10", features = ["derive"] }
Nå er vi klare for litt koding
Først så lager jeg mine kommando argumenter i structen Arguments (lite orginalt navn, men funker her).
use clap::Parser;
#[derive(Default, Debug, Parser)]
struct Arguments {
name: String,
age: usize,
}
I main funksjonen skriver jeg bare ut argumentene.
fn main() {
let args = Arguments::parse();
println!(":?", args)
}
Jeg installerer appen i stedet for å kjøre cargo run -- arg1 arg2 --flagg
da jeg synes det gir ett mer riktig intrykk av hvordan CLI-apppen blir, det gjøres enkelt med :
cargo install --path .
Så teste CLI-appen, med det geniale navnet clap-cli
✹)──> clap-cli
error: the following required arguments were not provided:
<NAME>
<AGE>
Usage: clap-cli <NAME> <AGE>
For more information, try '--help'.
Så allerede en fungerende CLI-applikasjon, så la oss teste med -h
flagget.
✹)──> clap-cli -h
Usage: clap-cli <NAME> <AGE>
Arguments:
<NAME>
<AGE>
Options:
-h, --help Print help
Happy path.
✹)──> clap-cli Reidar 52
Arguments { name: "Reidar", age: 52 }
Mer makromagi
Vi kan legge på clap traitet, for å gi mer info for help, her legger jeg på version
som den henter fra Cargo.toml
fila og about
som den henter fra kommentarene over funksjonen
#[derive(Default, Debug, Parser)]
#[clap(author = "Amedia Utvikling", version, about)]
/// Demo app for Jotter blog
struct Arguments {
...
}
Som gir oss dette i konsollet.
✹)──> clap-cli -h
Demo app for Jotter blog
Usage: clap-cli <NAME> <AGE>
Arguments:
<NAME>
<AGE>
Options:
-h, --help Print help
-V, --version Print version
Legge på flagg
Her også får vi hjelp fra makroen clap
, legger denne inn i Arguments structen:
#[clap(short, long)]
/// For test run
test_run: bool,
Short og long, står for kort og langt flagg, det vil si -t
for short og --test-run
for long.
✹)──> clap-cli -h
Demo app for Jotter blog
Usage: clap-cli [OPTIONS] <NAME> <AGE>
Arguments:
<NAME>
<AGE>
Options:
-t, --test-run For test run
-h, --help Print help
-V, --version Print version
Jeg kan også gruppere flaggene, ved å legge på help_heading
#[clap(short, long, help_heading = "Test")]
/// For test run
test_run: bool,
Som vil gi oss dette resultatet:
✹)──> clap-cli -h
Demo app for Jotter blog
Usage: clap-cli [OPTIONS] <NAME> <AGE>
Arguments:
<NAME>
<AGE>
Options:
-h, --help Print help
-V, --version Print version
Test:
-t, --test-run For test run
I sin helhet, blir da Arguments
structen som dette :
#[derive(Default, Debug, Parser)]
#[clap(author = "Amedia Utvikling", version, about)]
/// Demo app for Jotter blog
struct Arguments {
name: String,
age: usize,
#[clap(short, long, help_heading = "Test")]
/// For test run
test_run: bool,
}
Konklusjon
Makroer gir mye kraft i parsing av kommandolinje argumenter, så helt klart mye boilerplate kode som blir borte her. Jeg savner litt strukturen til Cobra CMD, men trenger den kanskje ikke her.
Det er ingen tvil hos meg, jeg går over på clap og Rust for mine CLI-verktøy.