Merge pull request #4257 from epage/os_str

feat(parser): Support more types with `value_parser!`
This commit is contained in:
Ed Page 2022-09-26 10:50:14 -05:00 committed by GitHub
commit c5c3c00735
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 107 additions and 21 deletions

View file

@ -131,7 +131,7 @@ impl AsRef<[u8]> for Str {
impl AsRef<std::ffi::OsStr> for Str {
#[inline]
fn as_ref(&self) -> &std::ffi::OsStr {
(&**self).as_ref()
(**self).as_ref()
}
}

View file

@ -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 {
@ -2040,7 +2040,7 @@ pub mod via_prelude {
type Parser;
fn value_parser(&self) -> Self::Parser;
}
impl<P: ValueParserFactory> _ValueParserViaFactory for &&_AutoValueParser<P> {
impl<P: ValueParserFactory> _ValueParserViaFactory for &&&&&&_AutoValueParser<P> {
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<E: crate::ValueEnum + Clone + Send + Sync + 'static> _ValueParserViaValueEnum
for &_AutoValueParser<E>
for &&&&&_AutoValueParser<E>
{
type Output = EnumValueParser<E>;
@ -2063,19 +2063,79 @@ pub mod via_prelude {
}
}
#[doc(hidden)]
pub trait _ValueParserViaFromOsString: private::_ValueParserViaFromOsStringSealed {
fn value_parser(&self) -> _AnonymousValueParser;
}
impl<FromOsString> _ValueParserViaFromOsString for &&&&_AutoValueParser<FromOsString>
where
FromOsString: From<std::ffi::OsString> + std::any::Any + Clone + Send + Sync + 'static,
{
fn value_parser(&self) -> _AnonymousValueParser {
_AnonymousValueParser(
OsStringValueParser::new()
.map(|s| FromOsString::from(s))
.into(),
)
}
}
#[doc(hidden)]
pub trait _ValueParserViaFromOsStr: private::_ValueParserViaFromOsStrSealed {
fn value_parser(&self) -> _AnonymousValueParser;
}
impl<FromOsStr> _ValueParserViaFromOsStr for &&&_AutoValueParser<FromOsStr>
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| FromOsStr::from(&s))
.into(),
)
}
}
#[doc(hidden)]
pub trait _ValueParserViaFromString: private::_ValueParserViaFromStringSealed {
fn value_parser(&self) -> _AnonymousValueParser;
}
impl<FromString> _ValueParserViaFromString for &&_AutoValueParser<FromString>
where
FromString: From<String> + std::any::Any + Clone + Send + Sync + 'static,
{
fn value_parser(&self) -> _AnonymousValueParser {
_AnonymousValueParser(StringValueParser::new().map(|s| FromString::from(s)).into())
}
}
#[doc(hidden)]
pub trait _ValueParserViaFromStr: private::_ValueParserViaFromStrSealed {
fn value_parser(&self) -> _AnonymousValueParser;
}
impl<FromStr> _ValueParserViaFromStr for _AutoValueParser<FromStr>
impl<FromStr> _ValueParserViaFromStr for &_AutoValueParser<FromStr>
where
FromStr: std::str::FromStr + std::any::Any + Clone + Send + Sync + 'static,
<FromStr as std::str::FromStr>::Err:
Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
FromStr: for<'s> From<&'s str> + std::any::Any + Clone + Send + Sync + 'static,
{
fn value_parser(&self) -> _AnonymousValueParser {
let func: fn(&str) -> Result<FromStr, <FromStr as std::str::FromStr>::Err> =
FromStr::from_str;
_AnonymousValueParser(StringValueParser::new().map(|s| FromStr::from(&s)).into())
}
}
#[doc(hidden)]
pub trait _ValueParserViaParse: private::_ValueParserViaParseSealed {
fn value_parser(&self) -> _AnonymousValueParser;
}
impl<Parse> _ValueParserViaParse for _AutoValueParser<Parse>
where
Parse: std::str::FromStr + std::any::Any + Clone + Send + Sync + 'static,
<Parse as std::str::FromStr>::Err: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
{
fn value_parser(&self) -> _AnonymousValueParser {
let func: fn(&str) -> Result<Parse, <Parse as std::str::FromStr>::Err> =
Parse::from_str;
_AnonymousValueParser(ValueParser::new(func))
}
}
@ -2088,6 +2148,8 @@ 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<&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
@ -2155,28 +2217,52 @@ macro_rules! value_parser {
($name:ty) => {{
use $crate::builder::via_prelude::*;
let auto = $crate::builder::_AutoValueParser::<$name>::new();
(&&&auto).value_parser()
(&&&&&&auto).value_parser()
}};
}
mod private {
use super::*;
// Prefer these so `clap_derive` defaults to optimized implementations
pub trait _ValueParserViaSelfSealed {}
impl<P: Into<ValueParser>> _ValueParserViaSelfSealed for &&&_AutoValueParser<P> {}
impl<P: Into<ValueParser>> _ValueParserViaSelfSealed for &&&&&&&_AutoValueParser<P> {}
pub trait _ValueParserViaFactorySealed {}
impl<P: ValueParserFactory> _ValueParserViaFactorySealed for &&_AutoValueParser<P> {}
impl<P: ValueParserFactory> _ValueParserViaFactorySealed for &&&&&&_AutoValueParser<P> {}
pub trait _ValueParserViaValueEnumSealed {}
impl<E: crate::ValueEnum> _ValueParserViaValueEnumSealed for &_AutoValueParser<E> {}
impl<E: crate::ValueEnum> _ValueParserViaValueEnumSealed for &&&&&_AutoValueParser<E> {}
pub trait _ValueParserViaFromOsStringSealed {}
impl<FromOsString> _ValueParserViaFromOsStringSealed for &&&&_AutoValueParser<FromOsString> where
FromOsString: From<std::ffi::OsString> + std::any::Any + Send + Sync + 'static
{
}
pub trait _ValueParserViaFromOsStrSealed {}
impl<FromOsStr> _ValueParserViaFromOsStrSealed for &&&_AutoValueParser<FromOsStr> where
FromOsStr: for<'s> From<&'s std::ffi::OsStr> + std::any::Any + Send + Sync + 'static
{
}
pub trait _ValueParserViaFromStringSealed {}
impl<FromString> _ValueParserViaFromStringSealed for &&_AutoValueParser<FromString> where
FromString: From<String> + std::any::Any + Send + Sync + 'static
{
}
pub trait _ValueParserViaFromStrSealed {}
impl<FromStr> _ValueParserViaFromStrSealed for _AutoValueParser<FromStr>
impl<FromStr> _ValueParserViaFromStrSealed for &_AutoValueParser<FromStr> where
FromStr: for<'s> From<&'s str> + std::any::Any + Send + Sync + 'static
{
}
pub trait _ValueParserViaParseSealed {}
impl<Parse> _ValueParserViaParseSealed for _AutoValueParser<Parse>
where
FromStr: std::str::FromStr + std::any::Any + Send + Sync + 'static,
<FromStr as std::str::FromStr>::Err:
Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
Parse: std::str::FromStr + std::any::Any + Send + Sync + 'static,
<Parse as std::str::FromStr>::Err: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
{
}
}