Skip to content

Commit

Permalink
Merge pull request #4184 from epage/doc
Browse files Browse the repository at this point in the history
refactor(derive): Clean up in prep for parent attributes
  • Loading branch information
epage committed Sep 6, 2022
2 parents 7ed7f71 + ede8fd6 commit 088b396
Show file tree
Hide file tree
Showing 16 changed files with 237 additions and 347 deletions.
96 changes: 46 additions & 50 deletions clap_derive/src/derives/args.rs
Expand Up @@ -157,56 +157,40 @@ pub fn gen_augment(
parent_item: &Item,
override_required: bool,
) -> TokenStream {
let mut subcmds = fields.iter().filter_map(|(field, item)| {
let kind = item.kind();
if let Kind::Subcommand(ty) = &*kind {
let subcmd_type = match (**ty, sub_type(&field.ty)) {
(Ty::Option, Some(sub_type)) => sub_type,
_ => &field.ty,
};
let required = if **ty == Ty::Option {
quote!()
} else {
quote_spanned! { kind.span()=>
let #app_var = #app_var
.subcommand_required(true)
.arg_required_else_help(true);
}
};

let span = field.span();
let ts = if override_required {
quote! {
let #app_var = <#subcmd_type as clap::Subcommand>::augment_subcommands_for_update( #app_var );
}
} else{
quote! {
let #app_var = <#subcmd_type as clap::Subcommand>::augment_subcommands( #app_var );
#required
}
};
Some((span, ts))
} else {
None
}
});
let subcmd = subcmds.next().map(|(_, ts)| ts);
if let Some((span, _)) = subcmds.next() {
abort!(
span,
"multiple subcommand sets are not allowed, that's the second"
);
}

let mut subcommand_specified = false;
let args = fields.iter().filter_map(|(field, item)| {
let kind = item.kind();
match &*kind {
Kind::Command(_)
| Kind::Value(_)
| Kind::Subcommand(_)
| Kind::Value
| Kind::Skip(_, _)
| Kind::FromGlobal(_)
| Kind::ExternalSubcommand => None,
Kind::Subcommand(ty) => {
if subcommand_specified {
abort!(field.span(), "`#[command(subcommand)]` can only be used once per container");
}
subcommand_specified = true;

let subcmd_type = match (**ty, sub_type(&field.ty)) {
(Ty::Option, Some(sub_type)) => sub_type,
_ => &field.ty,
};
let implicit_methods = if **ty == Ty::Option || override_required {
quote!()
} else {
quote_spanned! { kind.span()=>
.subcommand_required(true)
.arg_required_else_help(true)
}
};

Some(quote! {
let #app_var = <#subcmd_type as clap::Subcommand>::augment_subcommands( #app_var );
let #app_var = #app_var
#implicit_methods;
})
}
Kind::Flatten => {
let ty = &field.ty;
let old_heading_var = format_ident!("__clap_old_heading");
Expand All @@ -215,14 +199,18 @@ pub fn gen_augment(
if override_required {
Some(quote_spanned! { kind.span()=>
let #old_heading_var = #app_var.get_next_help_heading().map(|s| clap::builder::Str::from(s.to_owned()));
let #app_var = #app_var #next_help_heading #next_display_order;
let #app_var = #app_var
#next_help_heading
#next_display_order;
let #app_var = <#ty as clap::Args>::augment_args_for_update(#app_var);
let #app_var = #app_var.next_help_heading(clap::builder::Resettable::from(#old_heading_var));
})
} else {
Some(quote_spanned! { kind.span()=>
let #old_heading_var = #app_var.get_next_help_heading().map(|s| clap::builder::Str::from(s.to_owned()));
let #app_var = #app_var #next_help_heading #next_display_order;
let #app_var = #app_var
#next_help_heading
#next_display_order;
let #app_var = <#ty as clap::Args>::augment_args(#app_var);
let #app_var = #app_var.next_help_heading(clap::builder::Resettable::from(#old_heading_var));
})
Expand Down Expand Up @@ -299,7 +287,7 @@ pub fn gen_augment(
};

let id = item.id();
let explicit_methods = item.field_methods(true);
let explicit_methods = item.field_methods();
let deprecations = if !override_required {
item.deprecations()
} else {
Expand Down Expand Up @@ -334,7 +322,6 @@ pub fn gen_augment(
#deprecations
let #app_var = #app_var #initial_app_methods;
#( #args )*
#subcmd
#app_var #final_app_methods
}}
}
Expand All @@ -346,7 +333,7 @@ pub fn gen_constructor(fields: &[(&Field, Item)]) -> TokenStream {
let arg_matches = format_ident!("__clap_arg_matches");
match &*kind {
Kind::Command(_)
| Kind::Value(_)
| Kind::Value
| Kind::ExternalSubcommand => {
abort! { kind.span(),
"`{}` cannot be used with `arg`",
Expand All @@ -370,13 +357,22 @@ pub fn gen_constructor(fields: &[(&Field, Item)]) -> TokenStream {
}
}
},
_ => {
Ty::Vec |
Ty::Other => {
quote_spanned! { kind.span()=>
#field_name: {
<#subcmd_type as clap::FromArgMatches>::from_arg_matches_mut(#arg_matches)?
}
}
},
Ty::OptionOption |
Ty::OptionVec => {
abort!(
ty.span(),
"{} types are not supported for subcommand",
ty.as_str()
);
}
}
}

Expand Down Expand Up @@ -417,7 +413,7 @@ pub fn gen_updater(fields: &[(&Field, Item)], use_self: bool) -> TokenStream {

match &*kind {
Kind::Command(_)
| Kind::Value(_)
| Kind::Value
| Kind::ExternalSubcommand => {
abort! { kind.span(),
"`{}` cannot be used with `arg`",
Expand Down
33 changes: 19 additions & 14 deletions clap_derive/src/derives/subcommand.rs
Expand Up @@ -137,7 +137,10 @@ fn gen_augment(
let kind = item.kind();

match &*kind {
Kind::Skip(_, _) => None,
Kind::Skip(_, _) |
Kind::Arg(_) |
Kind::FromGlobal(_) |
Kind::Value => None,

Kind::ExternalSubcommand => {
let ty = match variant.fields {
Expand All @@ -155,19 +158,17 @@ fn gen_augment(
} else {
quote!()
};
let subcommand = match subty_if_name(ty, "Vec") {
Some(subty) => {
quote_spanned! { kind.span()=>
#deprecations
let #app_var = #app_var.external_subcommand_value_parser(clap::value_parser!(#subty));
}
}

None => abort!(
let subty = subty_if_name(ty, "Vec").unwrap_or_else(|| {
abort!(
ty.span(),
"The type must be `Vec<_>` \
to be used with `external_subcommand`."
),
)
});
let subcommand = quote_spanned! { kind.span()=>
#deprecations
let #app_var = #app_var
.external_subcommand_value_parser(clap::value_parser!(#subty));
};
Some(subcommand)
}
Expand All @@ -187,15 +188,19 @@ fn gen_augment(
quote! {
#deprecations
let #old_heading_var = #app_var.get_next_help_heading().map(|s| clap::builder::Str::from(s.to_owned()));
let #app_var = #app_var #next_help_heading #next_display_order;
let #app_var = #app_var
#next_help_heading
#next_display_order;
let #app_var = <#ty as clap::Subcommand>::augment_subcommands_for_update(#app_var);
let #app_var = #app_var.next_help_heading(clap::builder::Resettable::from(#old_heading_var));
}
} else {
quote! {
#deprecations
let #old_heading_var = #app_var.get_next_help_heading().map(|s| clap::builder::Str::from(s.to_owned()));
let #app_var = #app_var #next_help_heading #next_display_order;
let #app_var = #app_var
#next_help_heading
#next_display_order;
let #app_var = <#ty as clap::Subcommand>::augment_subcommands(#app_var);
let #app_var = #app_var.next_help_heading(clap::builder::Resettable::from(#old_heading_var));
}
Expand Down Expand Up @@ -259,7 +264,7 @@ fn gen_augment(
Some(subcommand)
}

_ => {
Kind::Command(_) => {
let subcommand_var = Ident::new("__clap_subcommand", Span::call_site());
let sub_augment = match variant.fields {
Named(ref fields) => {
Expand Down
4 changes: 2 additions & 2 deletions clap_derive/src/derives/value_enum.rs
Expand Up @@ -42,7 +42,7 @@ pub fn derive_value_enum(input: &DeriveInput) -> TokenStream {
}

pub fn gen_for_enum(item: &Item, item_name: &Ident, variants: &[(&Variant, Item)]) -> TokenStream {
if !matches!(&*item.kind(), Kind::Value(_)) {
if !matches!(&*item.kind(), Kind::Value) {
abort! { item.kind().span(),
"`{}` cannot be used with `value`",
item.kind().name(),
Expand Down Expand Up @@ -84,7 +84,7 @@ fn lits(variants: &[(&Variant, Item)]) -> Vec<(TokenStream, Ident)> {
if !matches!(variant.fields, Fields::Unit) {
abort!(variant.span(), "`#[derive(ValueEnum)]` only supports unit variants. Non-unit variants must be skipped");
}
let fields = item.field_methods(false);
let fields = item.field_methods();
let deprecations = item.deprecations();
let name = item.cased_name();
Some((
Expand Down

0 comments on commit 088b396

Please sign in to comment.