diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a9903c6..ed2a17f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,12 @@ -# v0.3.6 (2019-12-22) +# v0.3.7 (2019-12-28) + +Nothing's new. Just re-release of `v0.3.6` due to +[the mess with versioning](https://github.com/TeXitoi/structopt/issues/315#issuecomment-568502792). + +You may notice that `structopt-derive` was bumped to `v0.4.0`, that's OK, it's not a breaking change. +`structopt` will pull the right version in on its on. + +# v0.3.6 (2019-12-22) - YANKED This is unusually big patch release. It contains a number of bugfixes and new features, some of them may theoretically be considered breaking. We did our best diff --git a/src/lib.rs b/src/lib.rs index 8e6f6b1e..70c0768c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -966,27 +966,24 @@ pub trait StructOpt { { Ok(Self::from_clap(&Self::clap().get_matches_from_safe(iter)?)) } +} - // All the following is NOT PUBLIC API!!! - // - // ** SUBJECT TO CHANGE WITHOUT NOTICE!!! ** - - #[doc(hidden)] - fn is_subcommand() -> bool { - unimplemented!() +/// This trait is NOT API. **SUBJECT TO CHANGE WITHOUT NOTICE!**. +#[doc(hidden)] +pub trait StructOptInternal: StructOpt { + fn augment_clap<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> { + app } - #[doc(hidden)] - fn augment_clap<'a, 'b>(_app: clap::App<'a, 'b>) -> clap::App<'a, 'b> { - unimplemented!() + fn is_subcommand() -> bool { + false } - #[doc(hidden)] fn from_subcommand<'a, 'b>(_sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option where - Self: Sized, + Self: std::marker::Sized, { - unimplemented!() + None } } @@ -998,19 +995,21 @@ impl StructOpt for Box { fn from_clap(matches: &clap::ArgMatches<'_>) -> Self { Box::new(::from_clap(matches)) } +} +impl StructOptInternal for Box { #[doc(hidden)] - fn augment_clap<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> { - ::augment_clap(app) + fn is_subcommand() -> bool { + ::is_subcommand() } #[doc(hidden)] - fn is_subcommand() -> bool { - ::is_subcommand() + fn from_subcommand<'a, 'b>(sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option { + ::from_subcommand(sub).map(Box::new) } #[doc(hidden)] - fn from_subcommand<'a, 'b>(sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option { - ::from_subcommand(sub).map(Box::new) + fn augment_clap<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> { + ::augment_clap(app) } } diff --git a/structopt-derive/src/lib.rs b/structopt-derive/src/lib.rs index 65f72e22..87eaf1f0 100644 --- a/structopt-derive/src/lib.rs +++ b/structopt-derive/src/lib.rs @@ -87,7 +87,9 @@ fn gen_augmentation( let span = field.span(); let ts = quote! { - let #app_var = <#subcmd_type as ::structopt::StructOpt>::augment_clap( #app_var ); + let #app_var = <#subcmd_type as ::structopt::StructOptInternal>::augment_clap( + #app_var + ); #required }; Some((span, ts)) @@ -116,8 +118,8 @@ fn gen_augmentation( Kind::FlattenStruct => { let ty = &field.ty; Some(quote_spanned! { kind.span()=> - let #app_var = <#ty as ::structopt::StructOpt>::augment_clap(#app_var); - let #app_var = if <#ty as ::structopt::StructOpt>::is_subcommand() { + let #app_var = <#ty as ::structopt::StructOptInternal>::augment_clap(#app_var); + let #app_var = if <#ty as ::structopt::StructOptInternal>::is_subcommand() { #app_var.setting(::structopt::clap::AppSettings::SubcommandRequiredElseHelp) } else { #app_var @@ -249,7 +251,7 @@ fn gen_constructor(fields: &Punctuated, parent_attribute: &Attrs) _ => quote_spanned!( ty.span()=> .unwrap() ), }; quote_spanned! { kind.span()=> - #field_name: <#subcmd_type as ::structopt::StructOpt>::from_subcommand( + #field_name: <#subcmd_type as ::structopt::StructOptInternal>::from_subcommand( matches.subcommand()) #unwrapper } @@ -396,7 +398,7 @@ fn gen_clap_struct(struct_attrs: &[Attribute]) -> GenOutput { let augmented_tokens = quote! { fn clap<'a, 'b>() -> ::structopt::clap::App<'a, 'b> { let app = #clap_tokens; - ::augment_clap(app) + ::augment_clap(app) } }; @@ -426,7 +428,7 @@ fn gen_clap_enum(enum_attrs: &[Attribute]) -> GenOutput { fn clap<'a, 'b>() -> ::structopt::clap::App<'a, 'b> { let app = #clap_tokens .setting(::structopt::clap::AppSettings::SubcommandRequiredElseHelp); - ::augment_clap(app) + ::augment_clap(app) } }; @@ -458,8 +460,10 @@ fn gen_augment_clap_enum( let ty = &unnamed[0]; quote_spanned! { ty.span()=> { - let #app_var = <#ty as ::structopt::StructOpt>::augment_clap(#app_var); - if <#ty as ::structopt::StructOpt>::is_subcommand() { + let #app_var = <#ty as ::structopt::StructOptInternal>::augment_clap( + #app_var + ); + if <#ty as ::structopt::StructOptInternal>::is_subcommand() { #app_var.setting( ::structopt::clap::AppSettings::SubcommandRequiredElseHelp ) @@ -498,7 +502,7 @@ fn gen_augment_clap_enum( fn gen_from_clap_enum(name: &Ident) -> TokenStream { quote! { fn from_clap(matches: &::structopt::clap::ArgMatches) -> Self { - <#name as ::structopt::StructOpt>::from_subcommand(matches.subcommand()) + <#name as ::structopt::StructOptInternal>::from_subcommand(matches.subcommand()) .unwrap() } } @@ -580,11 +584,18 @@ fn impl_structopt_for_struct( quote! { #[allow(unused_variables)] #[allow(unknown_lints)] - #[allow(clippy)] + #[allow(clippy::all)] #[allow(dead_code, unreachable_code)] impl ::structopt::StructOpt for #name { #clap_tokens #from_clap + } + + #[allow(unused_variables)] + #[allow(unknown_lints)] + #[allow(clippy::all)] + #[allow(dead_code, unreachable_code)] + impl ::structopt::StructOptInternal for #name { #augment_clap fn is_subcommand() -> bool { false } } @@ -613,6 +624,13 @@ fn impl_structopt_for_enum( impl ::structopt::StructOpt for #name { #clap_tokens #from_clap + } + + #[allow(unused_variables)] + #[allow(unknown_lints)] + #[allow(clippy::all)] + #[allow(dead_code, unreachable_code)] + impl ::structopt::StructOptInternal for #name { #augment_clap #from_subcommand fn is_subcommand() -> bool { true }