fix(derive): Allow partial update of Sub-Subcommands

When using `#[clap(subcommand)]` inside of a Subcommand, we didn't
properly do an `update` but a `from`.

This is a part of #2605
This commit is contained in:
Ed Page 2021-07-19 13:42:07 -05:00
parent 610d56d1c6
commit 746eb9d7bd
2 changed files with 75 additions and 3 deletions

View file

@ -154,9 +154,17 @@ fn gen_augment(
Unit => quote!( #app_var ),
Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
let ty = &unnamed[0];
quote_spanned! { ty.span()=>
{
<#ty as clap::Subcommand>::augment_subcommands(#app_var)
if override_required {
quote_spanned! { ty.span()=>
{
<#ty as clap::Subcommand>::augment_subcommands_for_update(#app_var)
}
}
} else {
quote_spanned! { ty.span()=>
{
<#ty as clap::Subcommand>::augment_subcommands(#app_var)
}
}
}
}

View file

@ -349,3 +349,67 @@ fn update_subcommands() {
opt.try_update_from(&["test", "command2", "43"]).unwrap();
assert_eq!(Opt::parse_from(&["test", "command2", "43"]), opt);
}
#[test]
fn update_sub_subcommands() {
#[derive(Clap, PartialEq, Debug)]
enum Opt {
#[clap(subcommand)]
Child1(Child1),
#[clap(subcommand)]
Child2(Child2),
}
#[derive(Clap, PartialEq, Debug)]
enum Child1 {
Command1(Command1),
Command2(Command2),
}
#[derive(Clap, PartialEq, Debug)]
enum Child2 {
Command1(Command1),
Command2(Command2),
}
#[derive(Clap, PartialEq, Debug)]
struct Command1 {
arg1: i32,
arg2: i32,
}
#[derive(Clap, PartialEq, Debug)]
struct Command2 {
arg2: i32,
}
// Full subcommand update
let mut opt = Opt::Child1(Child1::Command1(Command1 { arg1: 12, arg2: 14 }));
opt.try_update_from(&["test", "child1", "command1", "42", "44"])
.unwrap();
assert_eq!(
Opt::parse_from(&["test", "child1", "command1", "42", "44"]),
opt
);
// Partial subcommand update
let mut opt = Opt::Child1(Child1::Command1(Command1 { arg1: 12, arg2: 14 }));
opt.try_update_from(&["test", "child1", "command1", "42"])
.unwrap();
assert_eq!(
Opt::parse_from(&["test", "child1", "command1", "42", "14"]),
opt
);
// Partial subcommand update
let mut opt = Opt::Child1(Child1::Command1(Command1 { arg1: 12, arg2: 14 }));
opt.try_update_from(&["test", "child1", "command2", "43"])
.unwrap();
assert_eq!(Opt::parse_from(&["test", "child1", "command2", "43"]), opt);
// Change subcommand
let mut opt = Opt::Child1(Child1::Command1(Command1 { arg1: 12, arg2: 14 }));
opt.try_update_from(&["test", "child2", "command2", "43"])
.unwrap();
assert_eq!(Opt::parse_from(&["test", "child2", "command2", "43"]), opt);
}