diff --git a/CHANGELOG.md b/CHANGELOG.md index f4a810e28fcb..1388fec61d32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -183,6 +183,9 @@ Subtle changes (i.e. compiler won't catch): - `ArgAction::Count`, requiring `ArgMatches::get_count` instead of `ArgMatches::occurrences_of` - `ArgAction::Set`, requiring `ArgMatches::get_one` instead of `ArgMatches::value_of` - `ArgAction::Append`, requiring `ArgMatches::get_many` instead of `ArgMatches::values_of` +- `ArgAction::Set`, `ArgAction::SetTrue`, and `Arg::Action::SetFalse` now + conflict by default to be like `ArgAction::StoreValue` and + `ArgAction::IncOccurrences`, requiring `cmd.args_override_self(true)` to override instead (#4261) - By default, an `Arg`s default action is `ArgAction::Set`, rather than `ArgAction::IncOccurrence` to reduce confusing magic through consistency (#2687, #4032, see also #3977) - `mut_arg` can no longer be used to customize help and version arguments, instead disable them (`Command::disable_help_flag`, `Command::disable_version_flag`) and provide your own (#4056) - Removed lifetimes from `Command`, `Arg`, `ArgGroup`, and `PossibleValue`, assuming `'static`. `string` feature flag will enable support for `String`s (#1041, #2150, #4223) diff --git a/examples/tutorial_builder/03_01_flag_bool.md b/examples/tutorial_builder/03_01_flag_bool.md index c151af440a68..0842935f3f27 100644 --- a/examples/tutorial_builder/03_01_flag_bool.md +++ b/examples/tutorial_builder/03_01_flag_bool.md @@ -16,6 +16,11 @@ $ 03_01_flag_bool --verbose verbose: true $ 03_01_flag_bool --verbose --verbose -verbose: true +? failed +error: The argument '--verbose' cannot be used with '--verbose' + +Usage: 03_01_flag_bool[EXE] [OPTIONS] + +For more information try '--help' ``` diff --git a/examples/tutorial_derive/03_01_flag_bool.md b/examples/tutorial_derive/03_01_flag_bool.md index b5bfe58d811f..77975698e353 100644 --- a/examples/tutorial_derive/03_01_flag_bool.md +++ b/examples/tutorial_derive/03_01_flag_bool.md @@ -16,6 +16,11 @@ $ 03_01_flag_bool_derive --verbose verbose: true $ 03_01_flag_bool_derive --verbose --verbose -verbose: true +? failed +error: The argument '--verbose' cannot be used with '--verbose' + +Usage: 03_01_flag_bool_derive[EXE] [OPTIONS] + +For more information try '--help' ``` diff --git a/src/builder/action.rs b/src/builder/action.rs index 7cd3e017908c..dc7b79a74377 100644 --- a/src/builder/action.rs +++ b/src/builder/action.rs @@ -27,6 +27,10 @@ pub enum ArgAction { /// When encountered, store the associated value(s) in [`ArgMatches`][crate::ArgMatches] /// + /// **NOTE:** If the argument has previously been seen, it will result in a + /// [`ArgumentConflict`][crate::error::ErrorKind::ArgumentConflict] unless + /// [`Command::args_override_self(true)`][crate::Command::args_override_self] is set. + /// /// # Examples /// /// ```rust @@ -76,6 +80,10 @@ pub enum ArgAction { /// No value is allowed. To optionally accept a value, see /// [`Arg::default_missing_value`][super::Arg::default_missing_value] /// + /// **NOTE:** If the argument has previously been seen, it will result in a + /// [`ArgumentConflict`][crate::error::ErrorKind::ArgumentConflict] unless + /// [`Command::args_override_self(true)`][crate::Command::args_override_self] is set. + /// /// # Examples /// /// ```rust @@ -88,7 +96,7 @@ pub enum ArgAction { /// .action(clap::ArgAction::SetTrue) /// ); /// - /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); + /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap(); /// assert!(matches.contains_id("flag")); /// assert_eq!( /// matches.get_one::("flag").copied(), @@ -123,7 +131,7 @@ pub enum ArgAction { /// ) /// ); /// - /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); + /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap(); /// assert!(matches.contains_id("flag")); /// assert_eq!( /// matches.get_one::("flag").copied(), @@ -145,6 +153,10 @@ pub enum ArgAction { /// No value is allowed. To optionally accept a value, see /// [`Arg::default_missing_value`][super::Arg::default_missing_value] /// + /// **NOTE:** If the argument has previously been seen, it will result in a + /// [`ArgumentConflict`][crate::error::ErrorKind::ArgumentConflict] unless + /// [`Command::args_override_self(true)`][crate::Command::args_override_self] is set. + /// /// # Examples /// /// ```rust diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index 8a5ae1beff6f..7dcd07e132a1 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -657,7 +657,7 @@ pub trait TypedValueParser: Clone + Send + Sync + 'static { /// ) /// ); /// - /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); + /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap(); /// assert!(matches.contains_id("flag")); /// assert_eq!( /// matches.get_one::("flag").copied(), diff --git a/src/parser/matches/arg_matches.rs b/src/parser/matches/arg_matches.rs index e743ca876cd4..bcebb1fe0030 100644 --- a/src/parser/matches/arg_matches.rs +++ b/src/parser/matches/arg_matches.rs @@ -162,7 +162,7 @@ impl ArgMatches { /// .action(clap::ArgAction::SetTrue) /// ); /// - /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap(); + /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap(); /// assert!(matches.contains_id("flag")); /// assert_eq!( /// matches.get_flag("flag"), diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 190a1b54f4fc..c493630f9f14 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -1239,7 +1239,7 @@ impl<'cmd> Parser<'cmd> { raw_vals }; - if matcher.remove(&arg.id) && self.cmd.is_args_conflicts_with_self() { + if matcher.remove(&arg.id) && self.cmd.is_args_override_self() { return Err(ClapError::argument_conflict( self.cmd, arg.to_string(), diff --git a/tests/builder/action.rs b/tests/builder/action.rs index 6f4bcda2bf2b..d9b24873b852 100644 --- a/tests/builder/action.rs +++ b/tests/builder/action.rs @@ -1,6 +1,7 @@ #![allow(clippy::bool_assert_comparison)] use clap::builder::ArgPredicate; +use clap::error::ErrorKind; use clap::Arg; use clap::ArgAction; use clap::Command; @@ -22,8 +23,15 @@ fn set() { assert_eq!(matches.contains_id("mammal"), true); assert_eq!(matches.index_of("mammal"), Some(2)); + let result = cmd + .clone() + .try_get_matches_from(["test", "--mammal", "dog", "--mammal", "cat"]); + let err = result.err().unwrap(); + assert_eq!(err.kind(), ErrorKind::ArgumentConflict); + let matches = cmd .clone() + .args_override_self(true) .try_get_matches_from(["test", "--mammal", "dog", "--mammal", "cat"]) .unwrap(); assert_eq!(matches.get_one::("mammal").unwrap(), "cat"); @@ -88,8 +96,15 @@ fn set_true() { assert_eq!(matches.contains_id("mammal"), true); assert_eq!(matches.index_of("mammal"), Some(1)); + let result = cmd + .clone() + .try_get_matches_from(["test", "--mammal", "--mammal"]); + let err = result.err().unwrap(); + assert_eq!(err.kind(), ErrorKind::ArgumentConflict); + let matches = cmd .clone() + .args_override_self(true) .try_get_matches_from(["test", "--mammal", "--mammal"]) .unwrap(); assert_eq!(*matches.get_one::("mammal").unwrap(), true); diff --git a/tests/builder/app_settings.rs b/tests/builder/app_settings.rs index 723e15d6b075..c9c8cf5a525a 100644 --- a/tests/builder/app_settings.rs +++ b/tests/builder/app_settings.rs @@ -986,65 +986,11 @@ fn built_in_subcommand_escaped() { } } -#[test] -fn aaos_flags() { - // flags - let cmd = Command::new("posix").arg(arg!(--flag "some flag").action(ArgAction::SetTrue)); - - let res = cmd.clone().try_get_matches_from(vec!["", "--flag"]); - assert!(res.is_ok(), "{}", res.unwrap_err()); - let m = res.unwrap(); - assert!(m.contains_id("flag")); - assert!(*m.get_one::("flag").expect("defaulted by clap")); - - let res = cmd.try_get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]); - assert!(res.is_ok(), "{}", res.unwrap_err()); - let m = res.unwrap(); - assert!(m.contains_id("flag")); - assert!(*m.get_one::("flag").expect("defaulted by clap")); -} - -#[test] -fn aaos_flags_mult() { - // flags with multiple - let cmd = Command::new("posix").arg(arg!(--flag "some flag").action(ArgAction::Count)); - - let res = cmd.clone().try_get_matches_from(vec!["", "--flag"]); - assert!(res.is_ok(), "{}", res.unwrap_err()); - let m = res.unwrap(); - assert!(m.contains_id("flag")); - assert_eq!(*m.get_one::("flag").expect("defaulted by clap"), 1); - - let res = cmd.try_get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]); - assert!(res.is_ok(), "{}", res.unwrap_err()); - let m = res.unwrap(); - assert!(m.contains_id("flag")); - assert_eq!(*m.get_one::("flag").expect("defaulted by clap"), 4); -} - -#[test] -fn aaos_opts() { - // opts - let res = Command::new("posix") - .arg( - arg!(--opt "some option") - .required(true) - .action(ArgAction::Set), - ) - .try_get_matches_from(vec!["", "--opt=some", "--opt=other"]); - assert!(res.is_ok(), "{}", res.unwrap_err()); - let m = res.unwrap(); - assert!(m.contains_id("opt")); - assert_eq!( - m.get_one::("opt").map(|v| v.as_str()), - Some("other") - ); -} - #[test] fn aaos_opts_w_other_overrides() { // opts with other overrides let res = Command::new("posix") + .args_override_self(true) .arg(arg!(--opt "some option").action(ArgAction::Set)) .arg( arg!(--other "some other option") @@ -1066,6 +1012,7 @@ fn aaos_opts_w_other_overrides() { fn aaos_opts_w_other_overrides_rev() { // opts with other overrides, rev let res = Command::new("posix") + .args_override_self(true) .arg( arg!(--opt "some option") .required(true) @@ -1092,6 +1039,7 @@ fn aaos_opts_w_other_overrides_rev() { fn aaos_opts_w_other_overrides_2() { // opts with other overrides let res = Command::new("posix") + .args_override_self(true) .arg( arg!(--opt "some option") .overrides_with("other") @@ -1113,6 +1061,7 @@ fn aaos_opts_w_other_overrides_2() { fn aaos_opts_w_other_overrides_rev_2() { // opts with other overrides, rev let res = Command::new("posix") + .args_override_self(true) .arg( arg!(--opt "some option") .required(true) @@ -1259,6 +1208,7 @@ fn aaos_pos_mult() { #[test] fn aaos_option_use_delim_false() { let m = Command::new("posix") + .args_override_self(true) .arg( arg!(--opt "some option") .required(true) diff --git a/tests/builder/flags.rs b/tests/builder/flags.rs index 0f4d316f557e..e86adcdfc7b5 100644 --- a/tests/builder/flags.rs +++ b/tests/builder/flags.rs @@ -19,6 +19,7 @@ fn flag_using_short() { #[test] fn lots_o_flags_sep() { let r = Command::new("opts") + .args_override_self(true) .arg(arg!(o: -o ... "some flag").action(ArgAction::SetTrue)) .try_get_matches_from(vec![ "", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", @@ -53,6 +54,7 @@ fn lots_o_flags_sep() { #[test] fn lots_o_flags_combined() { let r = Command::new("opts") + .args_override_self(true) .arg(arg!(o: -o ... "some flag").action(ArgAction::SetTrue)) .try_get_matches_from(vec![ "", diff --git a/tests/builder/grouped_values.rs b/tests/builder/grouped_values.rs index a5336130be52..67df706ef547 100644 --- a/tests/builder/grouped_values.rs +++ b/tests/builder/grouped_values.rs @@ -223,6 +223,7 @@ fn grouped_interleaved_positional_occurrences() { #[test] fn issue_2171() { let schema = Command::new("ripgrep#1701 reproducer") + .args_override_self(true) .arg( Arg::new("pretty") .short('p') diff --git a/tests/builder/indices.rs b/tests/builder/indices.rs index 5f6d40deb793..dfe7d6651840 100644 --- a/tests/builder/indices.rs +++ b/tests/builder/indices.rs @@ -3,6 +3,7 @@ use clap::{Arg, ArgAction, Command}; #[test] fn indices_mult_opts() { let m = Command::new("ind") + .args_override_self(true) .arg( Arg::new("exclude") .short('e') @@ -32,6 +33,7 @@ fn indices_mult_opts() { #[test] fn index_mult_opts() { let m = Command::new("ind") + .args_override_self(true) .arg( Arg::new("exclude") .short('e') @@ -55,6 +57,7 @@ fn index_mult_opts() { #[test] fn index_flag() { let m = Command::new("ind") + .args_override_self(true) .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .try_get_matches_from(vec!["ind", "-e", "-i"]) @@ -67,6 +70,7 @@ fn index_flag() { #[test] fn index_flags() { let m = Command::new("ind") + .args_override_self(true) .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .try_get_matches_from(vec!["ind", "-e", "-i", "-e", "-e", "-i"]) @@ -79,6 +83,7 @@ fn index_flags() { #[test] fn indices_mult_flags() { let m = Command::new("ind") + .args_override_self(true) .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .try_get_matches_from(vec!["ind", "-e", "-i", "-e", "-e", "-i"]) @@ -91,6 +96,7 @@ fn indices_mult_flags() { #[test] fn indices_mult_flags_combined() { let m = Command::new("ind") + .args_override_self(true) .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .try_get_matches_from(vec!["ind", "-eieei"]) @@ -103,6 +109,7 @@ fn indices_mult_flags_combined() { #[test] fn indices_mult_flags_opt_combined() { let m = Command::new("ind") + .args_override_self(true) .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .arg(Arg::new("option").short('o').action(ArgAction::Set)) @@ -117,6 +124,7 @@ fn indices_mult_flags_opt_combined() { #[test] fn indices_mult_flags_opt_combined_eq() { let m = Command::new("ind") + .args_override_self(true) .arg(Arg::new("exclude").short('e').action(ArgAction::SetTrue)) .arg(Arg::new("include").short('i').action(ArgAction::SetTrue)) .arg(Arg::new("option").short('o').action(ArgAction::Set)) @@ -131,6 +139,7 @@ fn indices_mult_flags_opt_combined_eq() { #[test] fn indices_mult_opt_value_delim_eq() { let m = Command::new("myapp") + .args_override_self(true) .arg( Arg::new("option") .short('o') @@ -149,6 +158,7 @@ fn indices_mult_opt_value_delim_eq() { #[test] fn indices_mult_opt_value_no_delim_eq() { let m = Command::new("myapp") + .args_override_self(true) .arg( Arg::new("option") .short('o') @@ -163,6 +173,7 @@ fn indices_mult_opt_value_no_delim_eq() { #[test] fn indices_mult_opt_mult_flag() { let m = Command::new("myapp") + .args_override_self(true) .arg(Arg::new("option").short('o').action(ArgAction::Append)) .arg(Arg::new("flag").short('f').action(ArgAction::SetTrue)) .try_get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]) diff --git a/tests/builder/multiple_occurrences.rs b/tests/builder/multiple_occurrences.rs index 0b3d043a1d4f..09e50e62b2af 100644 --- a/tests/builder/multiple_occurrences.rs +++ b/tests/builder/multiple_occurrences.rs @@ -3,6 +3,7 @@ use clap::{arg, Arg, ArgAction, Command}; #[test] fn multiple_occurrences_of_flags_long() { let m = Command::new("mo_flags_long") + .args_override_self(true) .arg(arg!(--multflag "allowed multiple flag").action(ArgAction::SetTrue)) .arg(arg!(--flag "disallowed multiple flag").action(ArgAction::SetTrue)) .try_get_matches_from(vec!["", "--multflag", "--flag", "--multflag"]) @@ -16,6 +17,7 @@ fn multiple_occurrences_of_flags_long() { #[test] fn multiple_occurrences_of_flags_short() { let m = Command::new("mo_flags_short") + .args_override_self(true) .arg(arg!(-m --multflag "allowed multiple flag").action(ArgAction::SetTrue)) .arg(arg!(-f --flag "disallowed multiple flag").action(ArgAction::SetTrue)) .try_get_matches_from(vec!["", "-m", "-f", "-m"]) diff --git a/tests/builder/multiple_values.rs b/tests/builder/multiple_values.rs index fffe8162cc8e..83eec8b4770a 100644 --- a/tests/builder/multiple_values.rs +++ b/tests/builder/multiple_values.rs @@ -401,7 +401,7 @@ fn option_max_more() { #[test] fn optional_value() { - let mut cmd = Command::new("test").arg( + let mut cmd = Command::new("test").args_override_self(true).arg( Arg::new("port") .short('p') .value_name("NUM") diff --git a/tests/derive/flags.rs b/tests/derive/flags.rs index 16ec2473ddec..63fb216ae24d 100644 --- a/tests/derive/flags.rs +++ b/tests/derive/flags.rs @@ -21,6 +21,7 @@ use clap::Parser; #[test] fn bool_type_is_flag() { #[derive(Parser, PartialEq, Eq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short, long)] alice: bool, diff --git a/tests/derive/options.rs b/tests/derive/options.rs index e9049376de9e..d6420ab977b4 100644 --- a/tests/derive/options.rs +++ b/tests/derive/options.rs @@ -21,6 +21,7 @@ use clap::{Parser, Subcommand}; #[test] fn required_option() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short, long)] arg: i32, @@ -47,6 +48,7 @@ fn required_option() { #[test] fn option_with_default() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short, default_value = "42")] arg: i32, @@ -65,6 +67,7 @@ fn option_with_default() { #[test] fn option_with_raw_default() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short, default_value = "42")] arg: i32, @@ -94,6 +97,7 @@ fn option_from_str() { } #[derive(Debug, Parser, PartialEq)] + #[command(args_override_self = true)] struct Opt { a: Option, } @@ -119,6 +123,7 @@ fn vec_from_str() { } #[derive(Debug, Parser, PartialEq)] + #[command(args_override_self = true)] struct Opt { a: Vec, } @@ -147,6 +152,7 @@ fn option_vec_from_str() { } #[derive(Debug, Parser, PartialEq)] + #[command(args_override_self = true)] struct Opt { #[arg(short)] a: Option>, @@ -162,6 +168,7 @@ fn option_vec_from_str() { #[test] fn option_type_is_optional() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short)] arg: Option, @@ -181,6 +188,7 @@ fn option_type_is_optional() { fn required_with_option_type() { #[derive(Debug, PartialEq, Eq, Parser)] #[command(subcommand_negates_reqs = true)] + #[command(args_override_self = true)] struct Opt { #[arg(required = true)] req_str: Option, @@ -223,6 +231,7 @@ fn ignore_qualified_option_type() { } #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(value_parser = parser)] arg: ::std::option::Option, @@ -239,6 +248,7 @@ fn ignore_qualified_option_type() { #[test] fn option_option_type_is_optional_value() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short)] #[allow(clippy::option_option)] @@ -266,6 +276,7 @@ fn option_option_type_is_optional_value() { #[test] fn option_option_type_help() { #[derive(Parser, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(long, value_name = "val")] arg: Option>, @@ -278,6 +289,7 @@ fn option_option_type_help() { #[test] fn two_option_option_types() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short)] arg: Option>, @@ -332,6 +344,7 @@ fn two_option_option_types() { #[test] fn vec_type_is_multiple_occurrences() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short, long)] arg: Vec, @@ -350,6 +363,7 @@ fn vec_type_is_multiple_occurrences() { #[test] fn vec_type_with_required() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short, long, required = true)] arg: Vec, @@ -368,6 +382,7 @@ fn vec_type_with_required() { #[test] fn vec_type_with_multiple_values_only() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short, long, num_args(1..))] arg: Vec, @@ -390,6 +405,7 @@ fn ignore_qualified_vec_type() { } #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(value_parser = parser)] arg: ::std::vec::Vec, @@ -406,6 +422,7 @@ fn ignore_qualified_vec_type() { #[test] fn option_vec_type() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short)] arg: Option>, @@ -428,6 +445,7 @@ fn option_vec_type() { #[test] fn option_vec_type_structopt_behavior() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short, long, num_args(0..))] arg: Option>, @@ -455,6 +473,7 @@ fn option_vec_type_structopt_behavior() { #[test] fn two_option_vec_types() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(short)] arg: Option>, @@ -496,6 +515,7 @@ fn two_option_vec_types() { #[test] fn explicit_value_parser() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(long, value_parser = clap::value_parser!(i32))] arg: i32, @@ -509,6 +529,7 @@ fn explicit_value_parser() { #[test] fn implicit_value_parser() { #[derive(Parser, PartialEq, Debug)] + #[command(args_override_self = true)] struct Opt { #[arg(long)] arg: i32,