diff --git a/clap_derive/examples/arg_enum.rs b/clap_derive/examples/arg_enum.rs index 356c546f3a4..e233b053b4a 100644 --- a/clap_derive/examples/arg_enum.rs +++ b/clap_derive/examples/arg_enum.rs @@ -2,9 +2,9 @@ //! //! All the variants of the enum and the enum itself support `rename_all` -use clap::Clap; +use clap::{ArgEnum, Clap}; -#[derive(Clap, Debug, PartialEq)] +#[derive(ArgEnum, Debug, PartialEq)] enum ArgChoice { Foo, Bar, diff --git a/clap_derive/examples/value_hints_derive.rs b/clap_derive/examples/value_hints_derive.rs index 859411a1e64..0ecca5fb325 100644 --- a/clap_derive/examples/value_hints_derive.rs +++ b/clap_derive/examples/value_hints_derive.rs @@ -12,14 +12,14 @@ //! . ./value_hints_derive.fish //! ./target/debug/examples/value_hints_derive -- //! ``` -use clap::{App, AppSettings, Clap, IntoApp, ValueHint}; +use clap::{App, AppSettings, ArgEnum, Clap, IntoApp, ValueHint}; use clap_generate::generators::{Bash, Elvish, Fish, PowerShell, Zsh}; use clap_generate::{generate, Generator}; use std::ffi::OsString; use std::io; use std::path::PathBuf; -#[derive(Clap, Debug, PartialEq)] +#[derive(ArgEnum, Debug, PartialEq)] enum GeneratorChoice { Bash, Elvish, diff --git a/clap_derive/src/derives/clap.rs b/clap_derive/src/derives/clap.rs index bbf98329818..1ed64c9d581 100644 --- a/clap_derive/src/derives/clap.rs +++ b/clap_derive/src/derives/clap.rs @@ -13,7 +13,7 @@ // MIT/Apache 2.0 license. use crate::{ - derives::{arg_enum, from_arg_matches, into_app, subcommand}, + derives::{from_arg_matches, into_app, subcommand}, dummies, }; @@ -71,7 +71,6 @@ fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStream let into_app = into_app::gen_for_enum(name, attrs); let from_arg_matches = from_arg_matches::gen_for_enum(name); let subcommand = subcommand::gen_for_enum(name, attrs, e); - let arg_enum = arg_enum::gen_for_enum(name, attrs, e); quote! { impl clap::Clap for #name {} @@ -79,6 +78,5 @@ fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStream #into_app #from_arg_matches #subcommand - #arg_enum } } diff --git a/clap_derive/src/dummies.rs b/clap_derive/src/dummies.rs index 4749ac0d2f0..ea478de67d1 100644 --- a/clap_derive/src/dummies.rs +++ b/clap_derive/src/dummies.rs @@ -14,7 +14,6 @@ pub fn clap_enum(name: &Ident) { into_app(name); from_arg_matches(name); subcommand(name); - arg_enum(name); append_dummy(quote!( impl clap::Clap for #name {} )); } diff --git a/clap_derive/tests/arg_enum.rs b/clap_derive/tests/arg_enum.rs index 2ed7cfa9a3c..bb31496a23c 100644 --- a/clap_derive/tests/arg_enum.rs +++ b/clap_derive/tests/arg_enum.rs @@ -11,7 +11,7 @@ use clap::{ArgEnum, Clap}; #[test] fn basic() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] enum ArgChoice { Foo, Bar, @@ -40,7 +40,7 @@ fn basic() { #[test] fn multi_word_is_renamed_kebab() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] #[allow(non_camel_case_types)] enum ArgChoice { FooBar, @@ -70,7 +70,7 @@ fn multi_word_is_renamed_kebab() { #[test] fn variant_with_defined_casing() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] enum ArgChoice { #[clap(rename_all = "screaming_snake")] FooBar, @@ -93,7 +93,7 @@ fn variant_with_defined_casing() { #[test] fn casing_is_propogated_from_parent() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] #[clap(rename_all = "screaming_snake")] enum ArgChoice { FooBar, @@ -116,7 +116,7 @@ fn casing_is_propogated_from_parent() { #[test] fn casing_propogation_is_overridden() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] #[clap(rename_all = "screaming_snake")] enum ArgChoice { #[clap(rename_all = "camel")] @@ -141,7 +141,7 @@ fn casing_propogation_is_overridden() { #[test] fn case_insensitive() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] enum ArgChoice { Foo, } @@ -168,7 +168,7 @@ fn case_insensitive() { #[test] fn case_insensitive_set_to_false() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] enum ArgChoice { Foo, } @@ -190,7 +190,7 @@ fn case_insensitive_set_to_false() { #[test] fn alias() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] enum ArgChoice { #[clap(alias = "TOTP")] TOTP, @@ -218,7 +218,7 @@ fn alias() { #[test] fn multiple_alias() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] enum ArgChoice { #[clap(alias = "TOTP", alias = "t")] TOTP, @@ -252,7 +252,7 @@ fn multiple_alias() { #[test] fn option() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] enum ArgChoice { Foo, Bar, @@ -282,7 +282,7 @@ fn option() { #[test] fn vector() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] enum ArgChoice { Foo, Bar, @@ -312,7 +312,7 @@ fn vector() { #[test] fn from_str_invalid() { - #[derive(Clap, PartialEq, Debug)] + #[derive(ArgEnum, PartialEq, Debug)] enum ArgChoice { Foo, } diff --git a/src/derive.rs b/src/derive.rs index aad38d44ab3..9ee3d2cfc3b 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -206,12 +206,34 @@ pub trait Subcommand: Sized { fn augment_subcommands_for_update(app: App<'_>) -> App<'_>; } -/// @TODO @release @docs +/// Parse arguments into enums. +/// +/// When deriving [`Clap`], a field whose type implements `ArgEnum` can have the attribute +/// `#[clap(arg_enum)]`. In addition to parsing, help and error messages may report possible +/// variants. +/// +/// # Example +/// +/// ```rust +/// #[derive(clap::Clap)] +/// struct Args { +/// #[clap(arg_enum)] +/// level: Level, +/// } +/// +/// #[derive(clap::ArgEnum)] +/// enum Level { +/// Debug, +/// Info, +/// Warning, +/// Error, +/// } +/// ``` pub trait ArgEnum: Sized { - /// @TODO @release @docs + /// All possible argument choices, in display order. const VARIANTS: &'static [&'static str]; - /// @TODO @release @docs + /// Parse an argument into `Self`. fn from_str(input: &str, case_insensitive: bool) -> Result; }