From e64ed91a4ee0a6251e280f87c700d0d0cdd47b51 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 26 Sep 2022 07:47:01 -0500 Subject: [PATCH 1/6] feat(parser): Support From<&OsStr> types for `value_parser!` Last time I tried this, I wasn't able to resolve the lifetime issues. I seemed to have gotten it working this time. This came up in #4254. --- src/builder/value_parser.rs | 40 +++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index c5b97061..5a42b036 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -2040,7 +2040,7 @@ pub mod via_prelude { type Parser; fn value_parser(&self) -> Self::Parser; } - impl _ValueParserViaFactory for &&_AutoValueParser

{ + impl _ValueParserViaFactory for &&&_AutoValueParser

{ type Parser = P::Parser; fn value_parser(&self) -> Self::Parser { P::value_parser() @@ -2054,7 +2054,7 @@ pub mod via_prelude { fn value_parser(&self) -> Self::Output; } impl _ValueParserViaValueEnum - for &_AutoValueParser + for &&_AutoValueParser { type Output = EnumValueParser; @@ -2063,6 +2063,27 @@ pub mod via_prelude { } } + #[doc(hidden)] + pub trait _ValueParserViaFromOsStr: private::_ValueParserViaFromOsStrSealed { + fn value_parser(&self) -> _AnonymousValueParser; + } + impl _ValueParserViaFromOsStr for &_AutoValueParser + where + FromOsStr: + for<'s> From<&'s std::ffi::OsStr> + std::any::Any + Clone + Send + Sync + 'static, + { + fn value_parser(&self) -> _AnonymousValueParser { + _AnonymousValueParser( + OsStringValueParser::new() + .map(|s| { + let output = FromOsStr::from(&s); + output + }) + .into(), + ) + } + } + #[doc(hidden)] pub trait _ValueParserViaFromStr: private::_ValueParserViaFromStrSealed { fn value_parser(&self) -> _AnonymousValueParser; @@ -2088,6 +2109,7 @@ pub mod via_prelude { /// - [Native types][ValueParser]: `bool`, `String`, `OsString`, `PathBuf` /// - [Ranged numeric types][RangedI64ValueParser]: `u8`, `i8`, `u16`, `i16, `u32`, `i32`, `u64`, `i64` /// - [`ValueEnum` types][crate::ValueEnum] +/// - [`From<&OsStr>` types][std::convert::From] /// - [`FromStr` types][std::str::FromStr], including usize, isize /// /// # Example @@ -2155,7 +2177,7 @@ macro_rules! value_parser { ($name:ty) => {{ use $crate::builder::via_prelude::*; let auto = $crate::builder::_AutoValueParser::<$name>::new(); - (&&&auto).value_parser() + (&&&&auto).value_parser() }}; } @@ -2163,13 +2185,19 @@ mod private { use super::*; pub trait _ValueParserViaSelfSealed {} - impl> _ValueParserViaSelfSealed for &&&_AutoValueParser

{} + impl> _ValueParserViaSelfSealed for &&&&_AutoValueParser

{} pub trait _ValueParserViaFactorySealed {} - impl _ValueParserViaFactorySealed for &&_AutoValueParser

{} + impl _ValueParserViaFactorySealed for &&&_AutoValueParser

{} pub trait _ValueParserViaValueEnumSealed {} - impl _ValueParserViaValueEnumSealed for &_AutoValueParser {} + impl _ValueParserViaValueEnumSealed for &&_AutoValueParser {} + + pub trait _ValueParserViaFromOsStrSealed {} + impl _ValueParserViaFromOsStrSealed for &_AutoValueParser where + FromOsStr: for<'s> From<&'s std::ffi::OsStr> + std::any::Any + Send + Sync + 'static + { + } pub trait _ValueParserViaFromStrSealed {} impl _ValueParserViaFromStrSealed for _AutoValueParser From 9f49c0c63022e04c5218fb5f0ff89ce42cb3f62c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 26 Sep 2022 09:12:47 -0500 Subject: [PATCH 2/6] feat(parser): Support From for value_parser --- src/builder/value_parser.rs | 38 +++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index 5a42b036..c39f08c3 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -2040,7 +2040,7 @@ pub mod via_prelude { type Parser; fn value_parser(&self) -> Self::Parser; } - impl _ValueParserViaFactory for &&&_AutoValueParser

{ + impl _ValueParserViaFactory for &&&&_AutoValueParser

{ type Parser = P::Parser; fn value_parser(&self) -> Self::Parser { P::value_parser() @@ -2054,7 +2054,7 @@ pub mod via_prelude { fn value_parser(&self) -> Self::Output; } impl _ValueParserViaValueEnum - for &&_AutoValueParser + for &&&_AutoValueParser { type Output = EnumValueParser; @@ -2063,6 +2063,26 @@ pub mod via_prelude { } } + #[doc(hidden)] + pub trait _ValueParserViaFromOsString: private::_ValueParserViaFromOsStringSealed { + fn value_parser(&self) -> _AnonymousValueParser; + } + impl _ValueParserViaFromOsString for &&_AutoValueParser + where + FromOsString: From + std::any::Any + Clone + Send + Sync + 'static, + { + fn value_parser(&self) -> _AnonymousValueParser { + _AnonymousValueParser( + OsStringValueParser::new() + .map(|s| { + let output = FromOsString::from(s); + output + }) + .into(), + ) + } + } + #[doc(hidden)] pub trait _ValueParserViaFromOsStr: private::_ValueParserViaFromOsStrSealed { fn value_parser(&self) -> _AnonymousValueParser; @@ -2109,7 +2129,7 @@ pub mod via_prelude { /// - [Native types][ValueParser]: `bool`, `String`, `OsString`, `PathBuf` /// - [Ranged numeric types][RangedI64ValueParser]: `u8`, `i8`, `u16`, `i16, `u32`, `i32`, `u64`, `i64` /// - [`ValueEnum` types][crate::ValueEnum] -/// - [`From<&OsStr>` types][std::convert::From] +/// - [`From<&OsString>` types][std::convert::From] and [`From<&OsStr>` types][std::convert::From] /// - [`FromStr` types][std::str::FromStr], including usize, isize /// /// # Example @@ -2185,13 +2205,19 @@ mod private { use super::*; pub trait _ValueParserViaSelfSealed {} - impl> _ValueParserViaSelfSealed for &&&&_AutoValueParser

{} + impl> _ValueParserViaSelfSealed for &&&&&_AutoValueParser

{} pub trait _ValueParserViaFactorySealed {} - impl _ValueParserViaFactorySealed for &&&_AutoValueParser

{} + impl _ValueParserViaFactorySealed for &&&&_AutoValueParser

{} pub trait _ValueParserViaValueEnumSealed {} - impl _ValueParserViaValueEnumSealed for &&_AutoValueParser {} + impl _ValueParserViaValueEnumSealed for &&&_AutoValueParser {} + + pub trait _ValueParserViaFromOsStringSealed {} + impl _ValueParserViaFromOsStringSealed for &&_AutoValueParser where + FromOsString: From + std::any::Any + Send + Sync + 'static + { + } pub trait _ValueParserViaFromOsStrSealed {} impl _ValueParserViaFromOsStrSealed for &_AutoValueParser where From 76ec238b455945eca5600f5cb56984ccf2383ad7 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 26 Sep 2022 09:14:39 -0500 Subject: [PATCH 3/6] docs: Clarify value_parser implementation --- src/builder/value_parser.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index c39f08c3..3f61433b 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -1930,25 +1930,25 @@ pub trait ValueParserFactory { impl ValueParserFactory for String { type Parser = ValueParser; fn value_parser() -> Self::Parser { - ValueParser::string() + ValueParser::string() // Default `clap_derive` to optimized implementation } } impl ValueParserFactory for std::ffi::OsString { type Parser = ValueParser; fn value_parser() -> Self::Parser { - ValueParser::os_string() + ValueParser::os_string() // Default `clap_derive` to optimized implementation } } impl ValueParserFactory for std::path::PathBuf { type Parser = ValueParser; fn value_parser() -> Self::Parser { - ValueParser::path_buf() + ValueParser::path_buf() // Default `clap_derive` to optimized implementation } } impl ValueParserFactory for bool { type Parser = ValueParser; fn value_parser() -> Self::Parser { - ValueParser::bool() + ValueParser::bool() // Default `clap_derive` to optimized implementation } } impl ValueParserFactory for u8 { @@ -2204,6 +2204,7 @@ macro_rules! value_parser { mod private { use super::*; + // Prefer these so `clap_derive` defaults to optimized implementations pub trait _ValueParserViaSelfSealed {} impl> _ValueParserViaSelfSealed for &&&&&_AutoValueParser

{} From 931b6338f1258a12df29bfc8dbb3c5e839295258 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 26 Sep 2022 09:18:39 -0500 Subject: [PATCH 4/6] refactor(parser): Clarify FromStr from future FromStr --- src/builder/value_parser.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index 3f61433b..cfbfc238 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -2105,18 +2105,17 @@ pub mod via_prelude { } #[doc(hidden)] - pub trait _ValueParserViaFromStr: private::_ValueParserViaFromStrSealed { + pub trait _ValueParserViaParse: private::_ValueParserViaParseSealed { fn value_parser(&self) -> _AnonymousValueParser; } - impl _ValueParserViaFromStr for _AutoValueParser + impl _ValueParserViaParse for _AutoValueParser where - FromStr: std::str::FromStr + std::any::Any + Clone + Send + Sync + 'static, - ::Err: - Into>, + Parse: std::str::FromStr + std::any::Any + Clone + Send + Sync + 'static, + ::Err: Into>, { fn value_parser(&self) -> _AnonymousValueParser { - let func: fn(&str) -> Result::Err> = - FromStr::from_str; + let func: fn(&str) -> Result::Err> = + Parse::from_str; _AnonymousValueParser(ValueParser::new(func)) } } @@ -2226,12 +2225,11 @@ mod private { { } - pub trait _ValueParserViaFromStrSealed {} - impl _ValueParserViaFromStrSealed for _AutoValueParser + pub trait _ValueParserViaParseSealed {} + impl _ValueParserViaParseSealed for _AutoValueParser where - FromStr: std::str::FromStr + std::any::Any + Send + Sync + 'static, - ::Err: - Into>, + Parse: std::str::FromStr + std::any::Any + Send + Sync + 'static, + ::Err: Into>, { } } From 31f9234cc7e608dc77c501a224596a22b48144a5 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 26 Sep 2022 09:22:41 -0500 Subject: [PATCH 5/6] feat(parser): Add From and From --- src/builder/value_parser.rs | 73 ++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index cfbfc238..5d70f2fb 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -2040,7 +2040,7 @@ pub mod via_prelude { type Parser; fn value_parser(&self) -> Self::Parser; } - impl _ValueParserViaFactory for &&&&_AutoValueParser

{ + impl _ValueParserViaFactory for &&&&&&_AutoValueParser

{ type Parser = P::Parser; fn value_parser(&self) -> Self::Parser { P::value_parser() @@ -2054,7 +2054,7 @@ pub mod via_prelude { fn value_parser(&self) -> Self::Output; } impl _ValueParserViaValueEnum - for &&&_AutoValueParser + for &&&&&_AutoValueParser { type Output = EnumValueParser; @@ -2067,7 +2067,7 @@ pub mod via_prelude { pub trait _ValueParserViaFromOsString: private::_ValueParserViaFromOsStringSealed { fn value_parser(&self) -> _AnonymousValueParser; } - impl _ValueParserViaFromOsString for &&_AutoValueParser + impl _ValueParserViaFromOsString for &&&&_AutoValueParser where FromOsString: From + std::any::Any + Clone + Send + Sync + 'static, { @@ -2087,7 +2087,7 @@ pub mod via_prelude { pub trait _ValueParserViaFromOsStr: private::_ValueParserViaFromOsStrSealed { fn value_parser(&self) -> _AnonymousValueParser; } - impl _ValueParserViaFromOsStr for &_AutoValueParser + impl _ValueParserViaFromOsStr for &&&_AutoValueParser where FromOsStr: for<'s> From<&'s std::ffi::OsStr> + std::any::Any + Clone + Send + Sync + 'static, @@ -2104,6 +2104,46 @@ pub mod via_prelude { } } + #[doc(hidden)] + pub trait _ValueParserViaFromString: private::_ValueParserViaFromStringSealed { + fn value_parser(&self) -> _AnonymousValueParser; + } + impl _ValueParserViaFromString for &&_AutoValueParser + where + FromString: From + std::any::Any + Clone + Send + Sync + 'static, + { + fn value_parser(&self) -> _AnonymousValueParser { + _AnonymousValueParser( + StringValueParser::new() + .map(|s| { + let output = FromString::from(s); + output + }) + .into(), + ) + } + } + + #[doc(hidden)] + pub trait _ValueParserViaFromStr: private::_ValueParserViaFromStrSealed { + fn value_parser(&self) -> _AnonymousValueParser; + } + impl _ValueParserViaFromStr for &_AutoValueParser + where + FromStr: for<'s> From<&'s str> + std::any::Any + Clone + Send + Sync + 'static, + { + fn value_parser(&self) -> _AnonymousValueParser { + _AnonymousValueParser( + StringValueParser::new() + .map(|s| { + let output = FromStr::from(&s); + output + }) + .into(), + ) + } + } + #[doc(hidden)] pub trait _ValueParserViaParse: private::_ValueParserViaParseSealed { fn value_parser(&self) -> _AnonymousValueParser; @@ -2129,6 +2169,7 @@ pub mod via_prelude { /// - [Ranged numeric types][RangedI64ValueParser]: `u8`, `i8`, `u16`, `i16, `u32`, `i32`, `u64`, `i64` /// - [`ValueEnum` types][crate::ValueEnum] /// - [`From<&OsString>` types][std::convert::From] and [`From<&OsStr>` types][std::convert::From] +/// - [`From<&String>` types][std::convert::From] and [`From<&str>` types][std::convert::From] /// - [`FromStr` types][std::str::FromStr], including usize, isize /// /// # Example @@ -2196,7 +2237,7 @@ macro_rules! value_parser { ($name:ty) => {{ use $crate::builder::via_prelude::*; let auto = $crate::builder::_AutoValueParser::<$name>::new(); - (&&&&auto).value_parser() + (&&&&&&auto).value_parser() }}; } @@ -2205,26 +2246,38 @@ mod private { // Prefer these so `clap_derive` defaults to optimized implementations pub trait _ValueParserViaSelfSealed {} - impl> _ValueParserViaSelfSealed for &&&&&_AutoValueParser

{} + impl> _ValueParserViaSelfSealed for &&&&&&&_AutoValueParser

{} pub trait _ValueParserViaFactorySealed {} - impl _ValueParserViaFactorySealed for &&&&_AutoValueParser

{} + impl _ValueParserViaFactorySealed for &&&&&&_AutoValueParser

{} pub trait _ValueParserViaValueEnumSealed {} - impl _ValueParserViaValueEnumSealed for &&&_AutoValueParser {} + impl _ValueParserViaValueEnumSealed for &&&&&_AutoValueParser {} pub trait _ValueParserViaFromOsStringSealed {} - impl _ValueParserViaFromOsStringSealed for &&_AutoValueParser where + impl _ValueParserViaFromOsStringSealed for &&&&_AutoValueParser where FromOsString: From + std::any::Any + Send + Sync + 'static { } pub trait _ValueParserViaFromOsStrSealed {} - impl _ValueParserViaFromOsStrSealed for &_AutoValueParser where + impl _ValueParserViaFromOsStrSealed for &&&_AutoValueParser where FromOsStr: for<'s> From<&'s std::ffi::OsStr> + std::any::Any + Send + Sync + 'static { } + pub trait _ValueParserViaFromStringSealed {} + impl _ValueParserViaFromStringSealed for &&_AutoValueParser where + FromString: From + std::any::Any + Send + Sync + 'static + { + } + + pub trait _ValueParserViaFromStrSealed {} + impl _ValueParserViaFromStrSealed for &_AutoValueParser where + FromStr: for<'s> From<&'s str> + std::any::Any + Send + Sync + 'static + { + } + pub trait _ValueParserViaParseSealed {} impl _ValueParserViaParseSealed for _AutoValueParser where From bd6b67c60505ce13e447d65e5323d4633655ce91 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 26 Sep 2022 09:55:02 -0500 Subject: [PATCH 6/6] style: Make clippy happy --- src/builder/str.rs | 2 +- src/builder/value_parser.rs | 28 ++++------------------------ 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/src/builder/str.rs b/src/builder/str.rs index 8dd9a7f4..e4750c74 100644 --- a/src/builder/str.rs +++ b/src/builder/str.rs @@ -131,7 +131,7 @@ impl AsRef<[u8]> for Str { impl AsRef for Str { #[inline] fn as_ref(&self) -> &std::ffi::OsStr { - (&**self).as_ref() + (**self).as_ref() } } diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index 5d70f2fb..8a5ae1be 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -2074,10 +2074,7 @@ pub mod via_prelude { fn value_parser(&self) -> _AnonymousValueParser { _AnonymousValueParser( OsStringValueParser::new() - .map(|s| { - let output = FromOsString::from(s); - output - }) + .map(|s| FromOsString::from(s)) .into(), ) } @@ -2095,10 +2092,7 @@ pub mod via_prelude { fn value_parser(&self) -> _AnonymousValueParser { _AnonymousValueParser( OsStringValueParser::new() - .map(|s| { - let output = FromOsStr::from(&s); - output - }) + .map(|s| FromOsStr::from(&s)) .into(), ) } @@ -2113,14 +2107,7 @@ pub mod via_prelude { FromString: From + std::any::Any + Clone + Send + Sync + 'static, { fn value_parser(&self) -> _AnonymousValueParser { - _AnonymousValueParser( - StringValueParser::new() - .map(|s| { - let output = FromString::from(s); - output - }) - .into(), - ) + _AnonymousValueParser(StringValueParser::new().map(|s| FromString::from(s)).into()) } } @@ -2133,14 +2120,7 @@ pub mod via_prelude { FromStr: for<'s> From<&'s str> + std::any::Any + Clone + Send + Sync + 'static, { fn value_parser(&self) -> _AnonymousValueParser { - _AnonymousValueParser( - StringValueParser::new() - .map(|s| { - let output = FromStr::from(&s); - output - }) - .into(), - ) + _AnonymousValueParser(StringValueParser::new().map(|s| FromStr::from(&s)).into()) } }