Skip to content

Commit

Permalink
check option names conflict on debug build
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysd committed Nov 15, 2023
1 parent 8e64f97 commit 254430e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
38 changes: 24 additions & 14 deletions src/lib.rs
Expand Up @@ -178,8 +178,7 @@ impl Options {
hasarg: HasArg,
occur: Occur,
) -> &mut Options {
validate_names(short_name, long_name);
self.grps.push(OptGroup {
self.push_group(OptGroup {
short_name: short_name.to_string(),
long_name: long_name.to_string(),
hint: hint.to_string(),
Expand Down Expand Up @@ -207,8 +206,7 @@ impl Options {
/// assert!(matches.opt_present("h"));
/// ```
pub fn optflag(&mut self, short_name: &str, long_name: &str, desc: &str) -> &mut Options {
validate_names(short_name, long_name);
self.grps.push(OptGroup {
self.push_group(OptGroup {
short_name: short_name.to_string(),
long_name: long_name.to_string(),
hint: "".to_string(),
Expand Down Expand Up @@ -237,8 +235,7 @@ impl Options {
/// assert_eq!(2, matches.opt_count("v"));
/// ```
pub fn optflagmulti(&mut self, short_name: &str, long_name: &str, desc: &str) -> &mut Options {
validate_names(short_name, long_name);
self.grps.push(OptGroup {
self.push_group(OptGroup {
short_name: short_name.to_string(),
long_name: long_name.to_string(),
hint: "".to_string(),
Expand Down Expand Up @@ -277,8 +274,7 @@ impl Options {
desc: &str,
hint: &str,
) -> &mut Options {
validate_names(short_name, long_name);
self.grps.push(OptGroup {
self.push_group(OptGroup {
short_name: short_name.to_string(),
long_name: long_name.to_string(),
hint: hint.to_string(),
Expand Down Expand Up @@ -319,8 +315,7 @@ impl Options {
desc: &str,
hint: &str,
) -> &mut Options {
validate_names(short_name, long_name);
self.grps.push(OptGroup {
self.push_group(OptGroup {
short_name: short_name.to_string(),
long_name: long_name.to_string(),
hint: hint.to_string(),
Expand Down Expand Up @@ -360,8 +355,7 @@ impl Options {
desc: &str,
hint: &str,
) -> &mut Options {
validate_names(short_name, long_name);
self.grps.push(OptGroup {
self.push_group(OptGroup {
short_name: short_name.to_string(),
long_name: long_name.to_string(),
hint: hint.to_string(),
Expand Down Expand Up @@ -403,8 +397,7 @@ impl Options {
desc: &str,
hint: &str,
) -> &mut Options {
validate_names(short_name, long_name);
self.grps.push(OptGroup {
self.push_group(OptGroup {
short_name: short_name.to_string(),
long_name: long_name.to_string(),
hint: hint.to_string(),
Expand Down Expand Up @@ -680,6 +673,23 @@ impl Options {

Box::new(rows)
}

fn push_group(&mut self, group: OptGroup) {
validate_names(&group.short_name, &group.long_name);
#[cfg(debug_assertions)]
self.check_conflict(&group);
self.grps.push(group);
}

#[cfg(debug_assertions)]
fn check_conflict(&self, group: &OptGroup) {
if !group.short_name.is_empty() && self.grps.iter().any(|g| g.short_name == group.short_name) {
panic!("the short option name -{} caused conflict among multiple options", group.short_name);
}
if !group.long_name.is_empty() && self.grps.iter().any(|g| g.long_name == group.long_name) {
panic!("the long option name --{} caused conflict among multiple options", group.long_name);
}
}
}

fn validate_names(short_name: &str, long_name: &str) {
Expand Down
28 changes: 28 additions & 0 deletions src/tests/mod.rs
Expand Up @@ -1319,3 +1319,31 @@ fn test_opt_strs_pos() {
]
);
}

#[cfg(debug_assertions)]
#[test]
#[should_panic(expected = "the short option name -s caused conflict among multiple options")]
fn test_check_conflicts_in_short_name() {
let mut opts = Options::new();
opts.optflag("s", "long", "");
opts.optflag("s", "other", "");
}

#[cfg(debug_assertions)]
#[test]
#[should_panic(expected = "the long option name --long caused conflict among multiple options")]
fn test_check_conflicts_in_long_name() {
let mut opts = Options::new();
opts.optflag("a", "long", "");
opts.optflag("b", "long", "");
}

#[cfg(debug_assertions)]
#[test]
fn test_empty_names_should_not_cause_conflict() {
let mut opts = Options::new();
opts.optflag("", "long1", "");
opts.optflag("", "long2", "");
opts.optflag("a", "", "");
opts.optflag("b", "", "");
}

0 comments on commit 254430e

Please sign in to comment.