use clap::error::Error; use clap::{Arg, ArgAction, ArgMatches, Args, Command, FromArgMatches, Parser}; #[derive(Debug)] struct CliArgs { foo: bool, bar: bool, quuz: Option, } impl FromArgMatches for CliArgs { fn from_arg_matches(matches: &ArgMatches) -> Result { let mut matches = matches.clone(); Self::from_arg_matches_mut(&mut matches) } fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result { Ok(Self { foo: matches.get_flag("foo"), bar: matches.get_flag("bar"), quuz: matches.remove_one::("quuz"), }) } fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> { let mut matches = matches.clone(); self.update_from_arg_matches_mut(&mut matches) } fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> { self.foo |= matches.get_flag("foo"); self.bar |= matches.get_flag("bar"); if let Some(quuz) = matches.remove_one::("quuz") { self.quuz = Some(quuz); } Ok(()) } } impl Args for CliArgs { fn augment_args(cmd: Command) -> Command { cmd.arg( Arg::new("foo") .short('f') .long("foo") .action(ArgAction::SetTrue), ) .arg( Arg::new("bar") .short('b') .long("bar") .action(ArgAction::SetTrue), ) .arg( Arg::new("quuz") .short('q') .long("quuz") .action(ArgAction::Set), ) } fn augment_args_for_update(cmd: Command) -> Command { cmd.arg( Arg::new("foo") .short('f') .long("foo") .action(ArgAction::SetTrue), ) .arg( Arg::new("bar") .short('b') .long("bar") .action(ArgAction::SetTrue), ) .arg( Arg::new("quuz") .short('q') .long("quuz") .action(ArgAction::Set), ) } } #[derive(Parser, Debug)] struct Cli { #[arg(short, long)] top_level: bool, #[command(flatten)] more_args: CliArgs, } fn main() { let args = Cli::parse(); println!("{args:#?}"); }