mirror of
https://github.com/clap-rs/clap
synced 2024-11-10 23:04:23 +00:00
feat(macros): add macro to create custom enums to use as types
This commit is contained in:
parent
178c50ffe6
commit
fb672aff56
3 changed files with 83 additions and 2 deletions
39
examples/13a_EnumValuesAutomatic.rs
Normal file
39
examples/13a_EnumValuesAutomatic.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// You can use clap's value_t! macro with a custom enum by implementing the std::str::FromStr
|
||||
// trait which is very straight forward. There are two ways to do this, for simple enums you
|
||||
// can use clap's simple_enum! macro, but if you require additional functionality you can
|
||||
// create and implement the trait manually.
|
||||
//
|
||||
// In the following example we will create an enum with 4 values, assign a positional argument
|
||||
// that accepts only one of those values, and use clap to parse the argument.
|
||||
//
|
||||
// Start with bringing the trait into scope.
|
||||
|
||||
// Add clap like normal
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
|
||||
use clap::{App, Arg};
|
||||
|
||||
// Define your enum, the simple_num! macro takes a enum name followed by => and each value
|
||||
// separated by a ','
|
||||
simple_enum!{ Vals => Foo, Bar, Baz, Qux }
|
||||
|
||||
fn main() {
|
||||
// Create the application like normal
|
||||
let m = App::new("myapp")
|
||||
// Use a single positional argument that is required
|
||||
.arg(Arg::from_usage("<type> 'The type to use'")
|
||||
// Define the list of possible values
|
||||
.possible_values(vec!["Foo", "Bar", "Baz", "Qux"]))
|
||||
.get_matches();
|
||||
|
||||
let t = value_t_or_exit!(m.value_of("type"), Vals);
|
||||
|
||||
// Now we can use our enum like normal.
|
||||
match t {
|
||||
Vals::Foo => println!("Found a Foo"),
|
||||
Vals::Bar => println!("Found a Bar"),
|
||||
Vals::Baz => println!("Found a Baz"),
|
||||
Vals::Qux => println!("Found a Qux")
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// You can use clap's value_t! macro with a custom enum by implementing the std::str::FromStr
|
||||
// trait which is very straight forward.
|
||||
// If you require more complex configuration than simple_enum! provides, you can implement the
|
||||
// trait manually, as in the following example.
|
||||
//
|
||||
// In the following example we will create an enum with 4 values, assign a positional argument
|
||||
// that accepts only one of those values, and use clap to parse the argument.
|
|
@ -213,3 +213,45 @@ macro_rules! value_t_or_exit {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Convenience macro generated a simple enum with variants to be used as a type when parsing
|
||||
/// arguments.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # #[macro_use]
|
||||
/// # extern crate clap;
|
||||
/// # use clap::{App, Arg};
|
||||
/// simple_enum!{Foo => Bar, Baz, Qux}
|
||||
/// // Foo enum can now be used via Foo::Bar, or Foo::Baz, etc
|
||||
/// // and implements std::str::FromStr to use with the value_t! macros
|
||||
/// fn main() {
|
||||
/// let m = App::new("app")
|
||||
/// .arg(Arg::from_usage("<foo> 'the foo'")
|
||||
/// .possible_values(vec!["Bar", "Baz", "Qux"]))
|
||||
/// .get_matches();
|
||||
/// let f = value_t_or_exit!(m.value_of("foo"), Foo);
|
||||
///
|
||||
/// // Use f like any other Foo variant...
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! simple_enum {
|
||||
($e:ident => $($v:ident),+) => {
|
||||
enum $e {
|
||||
$($v),+
|
||||
}
|
||||
|
||||
impl<'a> std::str::FromStr for $e {
|
||||
type Err = &'a str;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self,<Self as std::str::FromStr>::Err> {
|
||||
match s {
|
||||
$(stringify!($v) => Ok($e::$v),)+
|
||||
_ => Err("no match")
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue