diff --git a/clap_derive/tests/arg_enum.rs b/clap_derive/tests/arg_enum.rs index 4ca646c617e3..809734ed8140 100644 --- a/clap_derive/tests/arg_enum.rs +++ b/clap_derive/tests/arg_enum.rs @@ -297,7 +297,41 @@ fn multiple_alias() { } #[test] -fn option() { +fn skip_variant() { + #[derive(ArgEnum, PartialEq, Debug, Clone)] + #[allow(dead_code)] // silence warning about `Baz` being unused + enum ArgChoice { + Foo, + Bar, + #[clap(skip)] + Baz, + } + + assert_eq!( + ArgChoice::value_variants() + .iter() + .map(ArgEnum::to_possible_value) + .map(Option::unwrap) + .collect::>(), + vec![PossibleValue::new("foo"), PossibleValue::new("bar")] + ); + assert!(ArgChoice::from_str("foo", true).is_ok()); + assert!(ArgChoice::from_str("bar", true).is_ok()); + assert!(ArgChoice::from_str("baz", true).is_err()); +} + +#[test] +fn from_str_invalid() { + #[derive(ArgEnum, PartialEq, Debug, Clone)] + enum ArgChoice { + Foo, + } + + assert!(ArgChoice::from_str("bar", true).is_err()); +} + +#[test] +fn option_type() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, @@ -327,7 +361,7 @@ fn option() { } #[test] -fn option_option() { +fn option_option_type() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, @@ -361,7 +395,7 @@ fn option_option() { } #[test] -fn vector() { +fn vec_type() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, @@ -391,7 +425,7 @@ fn vector() { } #[test] -fn option_vector() { +fn option_vec_type() { #[derive(ArgEnum, PartialEq, Debug, Clone)] enum ArgChoice { Foo, @@ -423,37 +457,3 @@ fn option_vector() { ); assert!(Opt::try_parse_from(&["", "-a", "fOo"]).is_err()); } - -#[test] -fn skip_variant() { - #[derive(ArgEnum, PartialEq, Debug, Clone)] - #[allow(dead_code)] // silence warning about `Baz` being unused - enum ArgChoice { - Foo, - Bar, - #[clap(skip)] - Baz, - } - - assert_eq!( - ArgChoice::value_variants() - .iter() - .map(ArgEnum::to_possible_value) - .map(Option::unwrap) - .collect::>(), - vec![PossibleValue::new("foo"), PossibleValue::new("bar")] - ); - assert!(ArgChoice::from_str("foo", true).is_ok()); - assert!(ArgChoice::from_str("bar", true).is_ok()); - assert!(ArgChoice::from_str("baz", true).is_err()); -} - -#[test] -fn from_str_invalid() { - #[derive(ArgEnum, PartialEq, Debug, Clone)] - enum ArgChoice { - Foo, - } - - assert!(ArgChoice::from_str("bar", true).is_err()); -} diff --git a/clap_derive/tests/arguments.rs b/clap_derive/tests/arguments.rs index e08b624ccd0f..2a1b0d113310 100644 --- a/clap_derive/tests/arguments.rs +++ b/clap_derive/tests/arguments.rs @@ -29,20 +29,6 @@ fn required_argument() { assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err()); } -#[test] -fn optional_argument() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - arg: Option, - } - assert_eq!( - Opt { arg: Some(42) }, - Opt::try_parse_from(&["test", "42"]).unwrap() - ); - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&["test"]).unwrap()); - assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err()); -} - #[test] fn argument_with_default() { #[derive(Parser, PartialEq, Debug)] @@ -58,45 +44,6 @@ fn argument_with_default() { assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err()); } -#[test] -fn arguments() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - arg: Vec, - } - assert_eq!( - Opt { arg: vec![24] }, - Opt::try_parse_from(&["test", "24"]).unwrap() - ); - assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!( - Opt { arg: vec![24, 42] }, - Opt::try_parse_from(&["test", "24", "42"]).unwrap() - ); -} - -#[test] -fn arguments_safe() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - arg: Vec, - } - assert_eq!( - Opt { arg: vec![24] }, - Opt::try_parse_from(&["test", "24"]).unwrap() - ); - assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!( - Opt { arg: vec![24, 42] }, - Opt::try_parse_from(&["test", "24", "42"]).unwrap() - ); - - assert_eq!( - clap::ErrorKind::ValueValidation, - Opt::try_parse_from(&["test", "NOPE"]).err().unwrap().kind - ); -} - #[test] fn auto_value_name() { #[derive(Parser, PartialEq, Debug)] @@ -136,3 +83,38 @@ fn explicit_value_name() { Opt::try_parse_from(&["test", "10"]).unwrap() ); } + +#[test] +fn option_type_is_optional() { + #[derive(Parser, PartialEq, Debug)] + struct Opt { + arg: Option, + } + assert_eq!( + Opt { arg: Some(42) }, + Opt::try_parse_from(&["test", "42"]).unwrap() + ); + assert_eq!(Opt { arg: None }, Opt::try_parse_from(&["test"]).unwrap()); + assert!(Opt::try_parse_from(&["test", "42", "24"]).is_err()); +} + +#[test] +fn vec_type_is_multiple_values() { + #[derive(Parser, PartialEq, Debug)] + struct Opt { + arg: Vec, + } + assert_eq!( + Opt { arg: vec![24] }, + Opt::try_parse_from(&["test", "24"]).unwrap() + ); + assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&["test"]).unwrap()); + assert_eq!( + Opt { arg: vec![24, 42] }, + Opt::try_parse_from(&["test", "24", "42"]).unwrap() + ); + assert_eq!( + clap::ErrorKind::ValueValidation, + Opt::try_parse_from(&["test", "NOPE"]).err().unwrap().kind + ); +} diff --git a/clap_derive/tests/basic.rs b/clap_derive/tests/basic.rs index 69f7ee298b9f..917fa6dd18aa 100644 --- a/clap_derive/tests/basic.rs +++ b/clap_derive/tests/basic.rs @@ -19,17 +19,12 @@ fn basic() { #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(short = 'a', long = "arg")] - arg: Vec, + arg: i32, } assert_eq!( - Opt { arg: vec![24] }, + Opt { arg: 24 }, Opt::try_parse_from(&["test", "-a24"]).unwrap() ); - assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&["test"]).unwrap()); - assert_eq!( - Opt { arg: vec![24, 42] }, - Opt::try_parse_from(&["test", "--arg", "24", "42"]).unwrap() - ); } #[test] diff --git a/clap_derive/tests/doc-comments-help.rs b/clap_derive/tests/doc-comments-help.rs index 1d6b0c2478e2..d502a2b699f5 100644 --- a/clap_derive/tests/doc-comments-help.rs +++ b/clap_derive/tests/doc-comments-help.rs @@ -108,7 +108,7 @@ fn top_long_doc_comment_both_help_long_help() { /// Or something else Foo { #[clap(about = "foo")] - bars: Vec, + bars: String, }, } diff --git a/clap_derive/tests/explicit_name_no_renaming.rs b/clap_derive/tests/explicit_name_no_renaming.rs index 8ea9955a7fb9..477fea2a4aea 100644 --- a/clap_derive/tests/explicit_name_no_renaming.rs +++ b/clap_derive/tests/explicit_name_no_renaming.rs @@ -7,15 +7,20 @@ use utils::*; fn explicit_short_long_no_rename() { #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(short = '.', long = ".foo", multiple_occurrences(true))] - foo: Vec, + #[clap(short = '.', long = ".foo")] + foo: String, } + assert_eq!( + Opt { foo: "long".into() }, + Opt::try_parse_from(&["test", "--.foo", "long"]).unwrap() + ); + assert_eq!( Opt { - foo: vec!["short".into(), "long".into()] + foo: "short".into(), }, - Opt::try_parse_from(&["test", "-.", "short", "--.foo", "long"]).unwrap() + Opt::try_parse_from(&["test", "-.", "short"]).unwrap() ); } @@ -24,9 +29,9 @@ fn explicit_name_no_rename() { #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(name = ".options")] - foo: Vec, + foo: String, } let help = get_long_help::(); - assert!(help.contains("[.options]...")) + assert!(help.contains("<.options>")) } diff --git a/clap_derive/tests/flags.rs b/clap_derive/tests/flags.rs index 9c57683a75cd..176c63691821 100644 --- a/clap_derive/tests/flags.rs +++ b/clap_derive/tests/flags.rs @@ -15,7 +15,7 @@ use clap::Parser; #[test] -fn unique_flag() { +fn bool_type_is_flag() { #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(short, long)] @@ -41,7 +41,7 @@ fn unique_flag() { } #[test] -fn multiple_flag() { +fn from_occurrences() { #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(short, long, parse(from_occurrences))] @@ -74,12 +74,12 @@ fn multiple_flag() { assert!(Opt::try_parse_from(&["test", "-a", "foo"]).is_err()); } -fn parse_from_flag(b: bool) -> std::sync::atomic::AtomicBool { - std::sync::atomic::AtomicBool::new(b) -} - #[test] -fn non_bool_flags() { +fn non_bool_type_flag() { + fn parse_from_flag(b: bool) -> std::sync::atomic::AtomicBool { + std::sync::atomic::AtomicBool::new(b) + } + #[derive(Parser, Debug)] struct Opt { #[clap(short, long, parse(from_flag = parse_from_flag))] @@ -106,7 +106,7 @@ fn non_bool_flags() { } #[test] -fn combined_flags() { +fn mixed_type_flags() { #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(short, long)] @@ -158,3 +158,32 @@ fn combined_flags() { Opt::try_parse_from(&["test", "-bb", "-a", "-bb"]).unwrap() ); } + +#[test] +fn ignore_qualified_bool_type() { + mod inner { + #[allow(non_camel_case_types)] + #[derive(PartialEq, Debug)] + pub struct bool(pub String); + + impl std::str::FromStr for self::bool { + type Err = String; + + fn from_str(s: &str) -> Result { + Ok(self::bool(s.into())) + } + } + } + + #[derive(Parser, PartialEq, Debug)] + struct Opt { + arg: inner::bool, + } + + assert_eq!( + Opt { + arg: inner::bool("success".into()) + }, + Opt::try_parse_from(&["test", "success"]).unwrap() + ); +} diff --git a/clap_derive/tests/help.rs b/clap_derive/tests/help.rs index b14a37221e21..48de630164f0 100644 --- a/clap_derive/tests/help.rs +++ b/clap_derive/tests/help.rs @@ -6,10 +6,10 @@ fn arg_help_heading_applied() { struct CliOptions { #[clap(long)] #[clap(help_heading = Some("HEADING A"))] - should_be_in_section_a: Option, + should_be_in_section_a: u32, #[clap(long)] - no_section: Option, + no_section: u32, } let app = CliOptions::into_app(); @@ -34,10 +34,10 @@ fn app_help_heading_applied() { struct CliOptions { #[clap(long)] #[clap(help_heading = Some("HEADING A"))] - should_be_in_section_a: Option, + should_be_in_section_a: u32, #[clap(long)] - should_be_in_default_section: Option, + should_be_in_default_section: u32, } let app = CliOptions::into_app(); @@ -72,21 +72,21 @@ fn app_help_heading_flattened() { sub_a: SubA, #[clap(long)] - should_be_in_default_section: Option, + should_be_in_default_section: u32, } #[derive(Debug, Clone, Args)] #[clap(help_heading = "HEADING A")] struct OptionsA { #[clap(long)] - should_be_in_section_a: Option, + should_be_in_section_a: u32, } #[derive(Debug, Clone, Args)] #[clap(help_heading = "HEADING B")] struct OptionsB { #[clap(long)] - should_be_in_section_b: Option, + should_be_in_section_b: u32, } #[derive(Debug, Clone, Subcommand)] @@ -98,20 +98,20 @@ fn app_help_heading_flattened() { SubAOne, #[clap(help_heading = "SUB A")] SubATwo { - should_be_in_sub_a: Option, + should_be_in_sub_a: u32, }, } #[derive(Debug, Clone, Subcommand)] enum SubB { #[clap(help_heading = "SUB B")] - SubBOne { should_be_in_sub_b: Option }, + SubBOne { should_be_in_sub_b: u32 }, } #[derive(Debug, Clone, Subcommand)] enum SubC { #[clap(help_heading = "SUB C")] - SubCOne { should_be_in_sub_c: Option }, + SubCOne { should_be_in_sub_c: u32 }, } let app = CliOptions::into_app(); @@ -172,7 +172,7 @@ fn flatten_field_with_help_heading() { #[derive(Debug, Clone, Args)] struct OptionsA { #[clap(long)] - should_be_in_section_a: Option, + should_be_in_section_a: u32, } let app = CliOptions::into_app(); diff --git a/clap_derive/tests/issues.rs b/clap_derive/tests/issues.rs index 1e4730c466f7..4201cd4209c6 100644 --- a/clap_derive/tests/issues.rs +++ b/clap_derive/tests/issues.rs @@ -63,7 +63,7 @@ fn issue_324() { #[clap(version = my_version())] struct Opt { #[clap(subcommand)] - _cmd: Option, + _cmd: SubCommand, } #[derive(Subcommand)] diff --git a/clap_derive/tests/nested.rs b/clap_derive/tests/macros.rs similarity index 100% rename from clap_derive/tests/nested.rs rename to clap_derive/tests/macros.rs diff --git a/clap_derive/tests/options.rs b/clap_derive/tests/options.rs index 9d62ff8e4f90..04e8d5636e7f 100644 --- a/clap_derive/tests/options.rs +++ b/clap_derive/tests/options.rs @@ -42,21 +42,6 @@ fn required_option() { assert!(Opt::try_parse_from(&["test", "-a42", "-a24"]).is_err()); } -#[test] -fn optional_option() { - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(short)] - arg: Option, - } - assert_eq!( - Opt { arg: Some(42) }, - Opt::try_parse_from(&["test", "-a42"]).unwrap() - ); - assert_eq!(Opt { arg: None }, Opt::try_parse_from(&["test"]).unwrap()); - assert!(Opt::try_parse_from(&["test", "-a42", "-a24"]).is_err()); -} - #[test] fn option_with_default() { #[derive(Parser, PartialEq, Debug)] @@ -88,66 +73,105 @@ fn option_with_raw_default() { } #[test] -fn options() { - #[derive(Parser, PartialEq, Debug)] +fn option_from_str() { + #[derive(Debug, PartialEq)] + struct A; + + impl<'a> From<&'a str> for A { + fn from(_: &str) -> A { + A + } + } + + #[derive(Debug, Parser, PartialEq)] struct Opt { - #[clap(short, long, multiple_occurrences(true))] - arg: Vec, + #[clap(parse(from_str))] + a: Option, } + + assert_eq!(Opt { a: None }, Opt::try_parse_from(&["test"]).unwrap()); assert_eq!( - Opt { arg: vec![24] }, - Opt::try_parse_from(&["test", "-a24"]).unwrap() + Opt { a: Some(A) }, + Opt::try_parse_from(&["test", "foo"]).unwrap() ); - assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&["test"]).unwrap()); +} + +#[test] +fn option_type_is_optional() { + #[derive(Parser, PartialEq, Debug)] + struct Opt { + #[clap(short)] + arg: Option, + } assert_eq!( - Opt { arg: vec![24, 42] }, - Opt::try_parse_from(&["test", "-a24", "--arg", "42"]).unwrap() + Opt { arg: Some(42) }, + Opt::try_parse_from(&["test", "-a42"]).unwrap() ); + assert_eq!(Opt { arg: None }, Opt::try_parse_from(&["test"]).unwrap()); + assert!(Opt::try_parse_from(&["test", "-a42", "-a24"]).is_err()); } #[test] -fn default_value() { - #[derive(Parser, PartialEq, Debug)] +fn required_with_option_type() { + #[derive(Debug, PartialEq, Eq, Parser)] + #[clap(setting(clap::AppSettings::SubcommandsNegateReqs))] struct Opt { - #[clap(short, default_value = "test")] - arg: String, + #[clap(required = true)] + req_str: Option, + + #[clap(subcommand)] + cmd: Option, + } + + #[derive(Debug, PartialEq, Eq, Subcommand)] + enum SubCommands { + ExSub { + #[clap(short, long, parse(from_occurrences))] + verbose: u8, + }, } + assert_eq!( - Opt { arg: "test".into() }, - Opt::try_parse_from(&["test"]).unwrap() + Opt { + req_str: Some(("arg").into()), + cmd: None, + }, + Opt::try_parse_from(&["test", "arg"]).unwrap() ); + assert_eq!( - Opt { arg: "foo".into() }, - Opt::try_parse_from(&["test", "-afoo"]).unwrap() + Opt { + req_str: None, + cmd: Some(SubCommands::ExSub { verbose: 1 }), + }, + Opt::try_parse_from(&["test", "ex-sub", "-v"]).unwrap() ); + + assert!(Opt::try_parse_from(&["test"]).is_err()); } #[test] -fn option_from_str() { - #[derive(Debug, PartialEq)] - struct A; - - impl<'a> From<&'a str> for A { - fn from(_: &str) -> A { - A - } +fn ignore_qualified_option_type() { + fn parser(s: &str) -> Option { + Some(s.to_string()) } - #[derive(Debug, Parser, PartialEq)] + #[derive(Parser, PartialEq, Debug)] struct Opt { - #[clap(parse(from_str))] - a: Option, + #[clap(parse(from_str = parser))] + arg: ::std::option::Option, } - assert_eq!(Opt { a: None }, Opt::try_parse_from(&["test"]).unwrap()); assert_eq!( - Opt { a: Some(A) }, - Opt::try_parse_from(&["test", "foo"]).unwrap() + Opt { + arg: Some("success".into()) + }, + Opt::try_parse_from(&["test", "success"]).unwrap() ); } #[test] -fn optional_argument_for_optional_option() { +fn option_option_type_is_optional_value() { #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(short, multiple_occurrences(true))] @@ -169,7 +193,7 @@ fn optional_argument_for_optional_option() { } #[test] -fn option_option_help() { +fn option_option_type_help() { #[derive(Parser, Debug)] struct Opt { #[clap(long, value_name = "val")] @@ -181,7 +205,7 @@ fn option_option_help() { } #[test] -fn two_option_options() { +fn two_option_option_types() { #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(short)] @@ -235,7 +259,45 @@ fn two_option_options() { } #[test] -fn optional_vec() { +fn vec_type_is_multiple_occurrences() { + #[derive(Parser, PartialEq, Debug)] + struct Opt { + #[clap(short, long, multiple_occurrences(true))] + arg: Vec, + } + assert_eq!( + Opt { arg: vec![24] }, + Opt::try_parse_from(&["test", "-a24"]).unwrap() + ); + assert_eq!(Opt { arg: vec![] }, Opt::try_parse_from(&["test"]).unwrap()); + assert_eq!( + Opt { arg: vec![24, 42] }, + Opt::try_parse_from(&["test", "-a24", "--arg", "42"]).unwrap() + ); +} + +#[test] +fn ignore_qualified_vec_type() { + fn parser(s: &str) -> Vec { + vec![s.to_string()] + } + + #[derive(Parser, PartialEq, Debug)] + struct Opt { + #[clap(parse(from_str = parser))] + arg: ::std::vec::Vec, + } + + assert_eq!( + Opt { + arg: vec!["success".into()] + }, + Opt::try_parse_from(&["test", "success"]).unwrap() + ); +} + +#[test] +fn option_vec_type() { #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(short, multiple_occurrences(true))] @@ -295,7 +357,7 @@ fn optional_vec() { } #[test] -fn two_optional_vecs() { +fn two_option_vec_types() { #[derive(Parser, PartialEq, Debug)] struct Opt { #[clap(short, multiple_occurrences(true))] @@ -334,42 +396,3 @@ fn two_optional_vecs() { Opt::try_parse_from(&["test"]).unwrap() ); } - -#[test] -fn required_option_type() { - #[derive(Debug, PartialEq, Eq, Parser)] - #[clap(setting(clap::AppSettings::SubcommandsNegateReqs))] - struct Opt { - #[clap(required = true)] - req_str: Option, - - #[clap(subcommand)] - cmd: Option, - } - - #[derive(Debug, PartialEq, Eq, Subcommand)] - enum SubCommands { - ExSub { - #[clap(short, long, parse(from_occurrences))] - verbose: u8, - }, - } - - assert_eq!( - Opt { - req_str: Some(("arg").into()), - cmd: None, - }, - Opt::try_parse_from(&["test", "arg"]).unwrap() - ); - - assert_eq!( - Opt { - req_str: None, - cmd: Some(SubCommands::ExSub { verbose: 1 }), - }, - Opt::try_parse_from(&["test", "ex-sub", "-v"]).unwrap() - ); - - assert!(Opt::try_parse_from(&["test"]).is_err()); -} diff --git a/clap_derive/tests/privacy.rs b/clap_derive/tests/privacy.rs index b4609b8312dd..12b53b1f2b4a 100644 --- a/clap_derive/tests/privacy.rs +++ b/clap_derive/tests/privacy.rs @@ -30,7 +30,7 @@ mod subcommands { /// foo Foo { /// foo - bars: Vec, + bars: String, }, } } diff --git a/clap_derive/tests/raw_idents.rs b/clap_derive/tests/raw_idents.rs index 1091379c3b61..12c5d1658f0a 100644 --- a/clap_derive/tests/raw_idents.rs +++ b/clap_derive/tests/raw_idents.rs @@ -4,14 +4,21 @@ use clap::Parser; fn raw_idents() { #[derive(Parser, Debug, PartialEq)] struct Opt { - #[clap(short, long, multiple_occurrences(true))] - r#type: Vec, + #[clap(short, long)] + r#type: String, } assert_eq!( Opt { - r#type: vec!["long".into(), "short".into()] + r#type: "long".into() }, - Opt::try_parse_from(&["test", "--type", "long", "-t", "short"]).unwrap() + Opt::try_parse_from(&["test", "--type", "long"]).unwrap() + ); + + assert_eq!( + Opt { + r#type: "short".into() + }, + Opt::try_parse_from(&["test", "-t", "short"]).unwrap() ); } diff --git a/clap_derive/tests/special_types.rs b/clap_derive/tests/special_types.rs deleted file mode 100644 index e1f9d26eb796..000000000000 --- a/clap_derive/tests/special_types.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! Checks that types like `::std::option::Option` are not special - -use clap::Parser; - -#[rustversion::all(since(1.37), stable)] -#[test] -fn special_types_bool() { - mod inner { - #[allow(non_camel_case_types)] - #[derive(PartialEq, Debug)] - pub struct bool(pub String); - - impl std::str::FromStr for self::bool { - type Err = String; - - fn from_str(s: &str) -> Result { - Ok(self::bool(s.into())) - } - } - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - arg: inner::bool, - } - - assert_eq!( - Opt { - arg: inner::bool("success".into()) - }, - Opt::try_parse_from(&["test", "success"]).unwrap() - ); -} - -#[test] -fn special_types_option() { - fn parser(s: &str) -> Option { - Some(s.to_string()) - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(parse(from_str = parser))] - arg: ::std::option::Option, - } - - assert_eq!( - Opt { - arg: Some("success".into()) - }, - Opt::try_parse_from(&["test", "success"]).unwrap() - ); -} - -#[test] -fn special_types_vec() { - fn parser(s: &str) -> Vec { - vec![s.to_string()] - } - - #[derive(Parser, PartialEq, Debug)] - struct Opt { - #[clap(parse(from_str = parser))] - arg: ::std::vec::Vec, - } - - assert_eq!( - Opt { - arg: vec!["success".into()] - }, - Opt::try_parse_from(&["test", "success"]).unwrap() - ); -}