Merge pull request #2585 from epage/argenum

fix(derive): `Clap` should not derive `ArgEnum`
This commit is contained in:
Pavan Kumar Sunkara 2021-07-14 18:01:31 +01:00 committed by GitHub
commit 894be6799c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 23 deletions

View file

@ -2,9 +2,9 @@
//! //!
//! All the variants of the enum and the enum itself support `rename_all` //! 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 { enum ArgChoice {
Foo, Foo,
Bar, Bar,

View file

@ -12,14 +12,14 @@
//! . ./value_hints_derive.fish //! . ./value_hints_derive.fish
//! ./target/debug/examples/value_hints_derive --<TAB> //! ./target/debug/examples/value_hints_derive --<TAB>
//! ``` //! ```
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::generators::{Bash, Elvish, Fish, PowerShell, Zsh};
use clap_generate::{generate, Generator}; use clap_generate::{generate, Generator};
use std::ffi::OsString; use std::ffi::OsString;
use std::io; use std::io;
use std::path::PathBuf; use std::path::PathBuf;
#[derive(Clap, Debug, PartialEq)] #[derive(ArgEnum, Debug, PartialEq)]
enum GeneratorChoice { enum GeneratorChoice {
Bash, Bash,
Elvish, Elvish,

View file

@ -13,7 +13,7 @@
// MIT/Apache 2.0 license. // MIT/Apache 2.0 license.
use crate::{ use crate::{
derives::{arg_enum, from_arg_matches, into_app, subcommand}, derives::{from_arg_matches, into_app, subcommand},
dummies, 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 into_app = into_app::gen_for_enum(name, attrs);
let from_arg_matches = from_arg_matches::gen_for_enum(name); let from_arg_matches = from_arg_matches::gen_for_enum(name);
let subcommand = subcommand::gen_for_enum(name, attrs, e); let subcommand = subcommand::gen_for_enum(name, attrs, e);
let arg_enum = arg_enum::gen_for_enum(name, attrs, e);
quote! { quote! {
impl clap::Clap for #name {} impl clap::Clap for #name {}
@ -79,6 +78,5 @@ fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStream
#into_app #into_app
#from_arg_matches #from_arg_matches
#subcommand #subcommand
#arg_enum
} }
} }

View file

@ -14,7 +14,6 @@ pub fn clap_enum(name: &Ident) {
into_app(name); into_app(name);
from_arg_matches(name); from_arg_matches(name);
subcommand(name); subcommand(name);
arg_enum(name);
append_dummy(quote!( impl clap::Clap for #name {} )); append_dummy(quote!( impl clap::Clap for #name {} ));
} }

View file

@ -11,7 +11,7 @@ use clap::{ArgEnum, Clap};
#[test] #[test]
fn basic() { fn basic() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
enum ArgChoice { enum ArgChoice {
Foo, Foo,
Bar, Bar,
@ -40,7 +40,7 @@ fn basic() {
#[test] #[test]
fn multi_word_is_renamed_kebab() { fn multi_word_is_renamed_kebab() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
enum ArgChoice { enum ArgChoice {
FooBar, FooBar,
@ -70,7 +70,7 @@ fn multi_word_is_renamed_kebab() {
#[test] #[test]
fn variant_with_defined_casing() { fn variant_with_defined_casing() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
enum ArgChoice { enum ArgChoice {
#[clap(rename_all = "screaming_snake")] #[clap(rename_all = "screaming_snake")]
FooBar, FooBar,
@ -93,7 +93,7 @@ fn variant_with_defined_casing() {
#[test] #[test]
fn casing_is_propogated_from_parent() { fn casing_is_propogated_from_parent() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
#[clap(rename_all = "screaming_snake")] #[clap(rename_all = "screaming_snake")]
enum ArgChoice { enum ArgChoice {
FooBar, FooBar,
@ -116,7 +116,7 @@ fn casing_is_propogated_from_parent() {
#[test] #[test]
fn casing_propogation_is_overridden() { fn casing_propogation_is_overridden() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
#[clap(rename_all = "screaming_snake")] #[clap(rename_all = "screaming_snake")]
enum ArgChoice { enum ArgChoice {
#[clap(rename_all = "camel")] #[clap(rename_all = "camel")]
@ -141,7 +141,7 @@ fn casing_propogation_is_overridden() {
#[test] #[test]
fn case_insensitive() { fn case_insensitive() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
enum ArgChoice { enum ArgChoice {
Foo, Foo,
} }
@ -168,7 +168,7 @@ fn case_insensitive() {
#[test] #[test]
fn case_insensitive_set_to_false() { fn case_insensitive_set_to_false() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
enum ArgChoice { enum ArgChoice {
Foo, Foo,
} }
@ -190,7 +190,7 @@ fn case_insensitive_set_to_false() {
#[test] #[test]
fn alias() { fn alias() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
enum ArgChoice { enum ArgChoice {
#[clap(alias = "TOTP")] #[clap(alias = "TOTP")]
TOTP, TOTP,
@ -218,7 +218,7 @@ fn alias() {
#[test] #[test]
fn multiple_alias() { fn multiple_alias() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
enum ArgChoice { enum ArgChoice {
#[clap(alias = "TOTP", alias = "t")] #[clap(alias = "TOTP", alias = "t")]
TOTP, TOTP,
@ -252,7 +252,7 @@ fn multiple_alias() {
#[test] #[test]
fn option() { fn option() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
enum ArgChoice { enum ArgChoice {
Foo, Foo,
Bar, Bar,
@ -282,7 +282,7 @@ fn option() {
#[test] #[test]
fn vector() { fn vector() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
enum ArgChoice { enum ArgChoice {
Foo, Foo,
Bar, Bar,
@ -312,7 +312,7 @@ fn vector() {
#[test] #[test]
fn from_str_invalid() { fn from_str_invalid() {
#[derive(Clap, PartialEq, Debug)] #[derive(ArgEnum, PartialEq, Debug)]
enum ArgChoice { enum ArgChoice {
Foo, Foo,
} }

View file

@ -206,12 +206,34 @@ pub trait Subcommand: Sized {
fn augment_subcommands_for_update(app: App<'_>) -> App<'_>; 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 { pub trait ArgEnum: Sized {
/// @TODO @release @docs /// All possible argument choices, in display order.
const VARIANTS: &'static [&'static str]; const VARIANTS: &'static [&'static str];
/// @TODO @release @docs /// Parse an argument into `Self`.
fn from_str(input: &str, case_insensitive: bool) -> Result<Self, String>; fn from_str(input: &str, case_insensitive: bool) -> Result<Self, String>;
} }