• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use clap::{arg, builder::PossibleValue, command, value_parser, ValueEnum};
2 
3 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
4 enum Mode {
5     Fast,
6     Slow,
7 }
8 
9 // Can also be derived with feature flag `derive`
10 impl ValueEnum for Mode {
value_variants<'a>() -> &'a [Self]11     fn value_variants<'a>() -> &'a [Self] {
12         &[Mode::Fast, Mode::Slow]
13     }
14 
to_possible_value<'a>(&self) -> Option<PossibleValue>15     fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
16         Some(match self {
17             Mode::Fast => PossibleValue::new("fast").help("Run swiftly"),
18             Mode::Slow => PossibleValue::new("slow").help("Crawl slowly but steadily"),
19         })
20     }
21 }
22 
23 impl std::fmt::Display for Mode {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result24     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25         self.to_possible_value()
26             .expect("no values are skipped")
27             .get_name()
28             .fmt(f)
29     }
30 }
31 
32 impl std::str::FromStr for Mode {
33     type Err = String;
34 
from_str(s: &str) -> Result<Self, Self::Err>35     fn from_str(s: &str) -> Result<Self, Self::Err> {
36         for variant in Self::value_variants() {
37             if variant.to_possible_value().unwrap().matches(s, false) {
38                 return Ok(*variant);
39             }
40         }
41         Err(format!("invalid variant: {}", s))
42     }
43 }
44 
main()45 fn main() {
46     let matches = command!() // requires `cargo` feature
47         .arg(
48             arg!(<MODE>)
49                 .help("What mode to run the program in")
50                 .value_parser(value_parser!(Mode)),
51         )
52         .get_matches();
53 
54     // Note, it's safe to call unwrap() because the arg is required
55     match matches
56         .get_one::<Mode>("MODE")
57         .expect("'MODE' is required and parsing will fail if its missing")
58     {
59         Mode::Fast => {
60             println!("Hare");
61         }
62         Mode::Slow => {
63             println!("Tortoise");
64         }
65     }
66 }
67