• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::convert::TryInto;
2 use std::ops::RangeBounds;
3 
4 use crate::parser::AnyValue;
5 use crate::parser::AnyValueId;
6 
7 /// Parse/validate argument values
8 ///
9 /// Specified with [`Arg::value_parser`][crate::Arg::value_parser].
10 ///
11 /// `ValueParser` defines how to convert a raw argument value into a validated and typed value for
12 /// use within an application.
13 ///
14 /// See
15 /// - [`value_parser!`][crate::value_parser] for automatically selecting an implementation for a given type
16 /// - [`ValueParser::new`] for additional [`TypedValueParser`] that can be used
17 ///
18 /// # Example
19 ///
20 /// ```rust
21 /// let mut cmd = clap::Command::new("raw")
22 ///     .arg(
23 ///         clap::Arg::new("color")
24 ///             .long("color")
25 ///             .value_parser(["always", "auto", "never"])
26 ///             .default_value("auto")
27 ///     )
28 ///     .arg(
29 ///         clap::Arg::new("hostname")
30 ///             .long("hostname")
31 ///             .value_parser(clap::builder::NonEmptyStringValueParser::new())
32 ///             .action(clap::ArgAction::Set)
33 ///             .required(true)
34 ///     )
35 ///     .arg(
36 ///         clap::Arg::new("port")
37 ///             .long("port")
38 ///             .value_parser(clap::value_parser!(u16).range(3000..))
39 ///             .action(clap::ArgAction::Set)
40 ///             .required(true)
41 ///     );
42 ///
43 /// let m = cmd.try_get_matches_from_mut(
44 ///     ["cmd", "--hostname", "rust-lang.org", "--port", "3001"]
45 /// ).unwrap();
46 ///
47 /// let color: &String = m.get_one("color")
48 ///     .expect("default");
49 /// assert_eq!(color, "auto");
50 ///
51 /// let hostname: &String = m.get_one("hostname")
52 ///     .expect("required");
53 /// assert_eq!(hostname, "rust-lang.org");
54 ///
55 /// let port: u16 = *m.get_one("port")
56 ///     .expect("required");
57 /// assert_eq!(port, 3001);
58 /// ```
59 pub struct ValueParser(ValueParserInner);
60 
61 enum ValueParserInner {
62     // Common enough to optimize and for possible values
63     Bool,
64     // Common enough to optimize
65     String,
66     // Common enough to optimize
67     OsString,
68     // Common enough to optimize
69     PathBuf,
70     Other(Box<dyn AnyValueParser>),
71 }
72 
73 impl ValueParser {
74     /// Custom parser for argument values
75     ///
76     /// Pre-existing [`TypedValueParser`] implementations include:
77     /// - `Fn(&str) -> Result<T, E>`
78     /// - [`EnumValueParser`] and  [`PossibleValuesParser`] for static enumerated values
79     /// - [`BoolishValueParser`] and [`FalseyValueParser`] for alternative `bool` implementations
80     /// - [`RangedI64ValueParser`] and [`RangedU64ValueParser`]
81     /// - [`NonEmptyStringValueParser`]
82     ///
83     /// # Example
84     ///
85     /// ```rust
86     /// type EnvVar = (String, Option<String>);
87     /// fn parse_env_var(env: &str) -> Result<EnvVar, std::io::Error> {
88     ///     if let Some((var, value)) = env.split_once('=') {
89     ///         Ok((var.to_owned(), Some(value.to_owned())))
90     ///     } else {
91     ///         Ok((env.to_owned(), None))
92     ///     }
93     /// }
94     ///
95     /// let mut cmd = clap::Command::new("raw")
96     ///     .arg(
97     ///         clap::Arg::new("env")
98     ///             .value_parser(clap::builder::ValueParser::new(parse_env_var))
99     ///             .required(true)
100     ///     );
101     ///
102     /// let m = cmd.try_get_matches_from_mut(["cmd", "key=value"]).unwrap();
103     /// let port: &EnvVar = m.get_one("env")
104     ///     .expect("required");
105     /// assert_eq!(*port, ("key".into(), Some("value".into())));
106     /// ```
new<P>(other: P) -> Self where P: TypedValueParser,107     pub fn new<P>(other: P) -> Self
108     where
109         P: TypedValueParser,
110     {
111         Self(ValueParserInner::Other(Box::new(other)))
112     }
113 
114     /// [`bool`] parser for argument values
115     ///
116     /// See also:
117     /// - [`BoolishValueParser`] for different human readable bool representations
118     /// - [`FalseyValueParser`] for assuming non-false is true
119     ///
120     /// # Example
121     ///
122     /// ```rust
123     /// let mut cmd = clap::Command::new("raw")
124     ///     .arg(
125     ///         clap::Arg::new("download")
126     ///             .value_parser(clap::value_parser!(bool))
127     ///             .required(true)
128     ///     );
129     ///
130     /// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap();
131     /// let port: bool = *m.get_one("download")
132     ///     .expect("required");
133     /// assert_eq!(port, true);
134     ///
135     /// assert!(cmd.try_get_matches_from_mut(["cmd", "forever"]).is_err());
136     /// ```
bool() -> Self137     pub const fn bool() -> Self {
138         Self(ValueParserInner::Bool)
139     }
140 
141     /// [`String`] parser for argument values
142     ///
143     /// See also:
144     /// - [`NonEmptyStringValueParser`]
145     ///
146     /// # Example
147     ///
148     /// ```rust
149     /// let mut cmd = clap::Command::new("raw")
150     ///     .arg(
151     ///         clap::Arg::new("port")
152     ///             .value_parser(clap::value_parser!(String))
153     ///             .required(true)
154     ///     );
155     ///
156     /// let m = cmd.try_get_matches_from_mut(["cmd", "80"]).unwrap();
157     /// let port: &String = m.get_one("port")
158     ///     .expect("required");
159     /// assert_eq!(port, "80");
160     /// ```
string() -> Self161     pub const fn string() -> Self {
162         Self(ValueParserInner::String)
163     }
164 
165     /// [`OsString`][std::ffi::OsString] parser for argument values
166     ///
167     /// # Example
168     ///
169     #[cfg_attr(not(unix), doc = " ```ignore")]
170     #[cfg_attr(unix, doc = " ```rust")]
171     /// # use clap::{Command, Arg, builder::ValueParser};
172     /// use std::ffi::OsString;
173     /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
174     /// let r = Command::new("myprog")
175     ///     .arg(
176     ///         Arg::new("arg")
177     ///         .required(true)
178     ///         .value_parser(ValueParser::os_string())
179     ///     )
180     ///     .try_get_matches_from(vec![
181     ///         OsString::from("myprog"),
182     ///         OsString::from_vec(vec![0xe9])
183     ///     ]);
184     ///
185     /// assert!(r.is_ok());
186     /// let m = r.unwrap();
187     /// let arg: &OsString = m.get_one("arg")
188     ///     .expect("required");
189     /// assert_eq!(arg.as_bytes(), &[0xe9]);
190     /// ```
os_string() -> Self191     pub const fn os_string() -> Self {
192         Self(ValueParserInner::OsString)
193     }
194 
195     /// [`PathBuf`][std::path::PathBuf] parser for argument values
196     ///
197     /// # Example
198     ///
199     /// ```rust
200     /// # use std::path::PathBuf;
201     /// # use std::path::Path;
202     /// let mut cmd = clap::Command::new("raw")
203     ///     .arg(
204     ///         clap::Arg::new("output")
205     ///             .value_parser(clap::value_parser!(PathBuf))
206     ///             .required(true)
207     ///     );
208     ///
209     /// let m = cmd.try_get_matches_from_mut(["cmd", "hello.txt"]).unwrap();
210     /// let port: &PathBuf = m.get_one("output")
211     ///     .expect("required");
212     /// assert_eq!(port, Path::new("hello.txt"));
213     ///
214     /// assert!(cmd.try_get_matches_from_mut(["cmd", ""]).is_err());
215     /// ```
path_buf() -> Self216     pub const fn path_buf() -> Self {
217         Self(ValueParserInner::PathBuf)
218     }
219 }
220 
221 impl ValueParser {
222     /// Parse into a `AnyValue`
223     ///
224     /// When `arg` is `None`, an external subcommand value is being parsed.
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<AnyValue, crate::Error>225     pub(crate) fn parse_ref(
226         &self,
227         cmd: &crate::Command,
228         arg: Option<&crate::Arg>,
229         value: &std::ffi::OsStr,
230     ) -> Result<AnyValue, crate::Error> {
231         self.any_value_parser().parse_ref(cmd, arg, value)
232     }
233 
234     /// Describes the content of `AnyValue`
type_id(&self) -> AnyValueId235     pub fn type_id(&self) -> AnyValueId {
236         self.any_value_parser().type_id()
237     }
238 
239     /// Reflect on enumerated value properties
240     ///
241     /// Error checking should not be done with this; it is mostly targeted at user-facing
242     /// applications like errors and completion.
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>243     pub fn possible_values(
244         &self,
245     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
246         self.any_value_parser().possible_values()
247     }
248 
any_value_parser(&self) -> &dyn AnyValueParser249     fn any_value_parser(&self) -> &dyn AnyValueParser {
250         match &self.0 {
251             ValueParserInner::Bool => &BoolValueParser {},
252             ValueParserInner::String => &StringValueParser {},
253             ValueParserInner::OsString => &OsStringValueParser {},
254             ValueParserInner::PathBuf => &PathBufValueParser {},
255             ValueParserInner::Other(o) => o.as_ref(),
256         }
257     }
258 }
259 
260 /// Convert a [`TypedValueParser`] to [`ValueParser`]
261 ///
262 /// # Example
263 ///
264 /// ```rust
265 /// let mut cmd = clap::Command::new("raw")
266 ///     .arg(
267 ///         clap::Arg::new("hostname")
268 ///             .long("hostname")
269 ///             .value_parser(clap::builder::NonEmptyStringValueParser::new())
270 ///             .action(clap::ArgAction::Set)
271 ///             .required(true)
272 ///     );
273 ///
274 /// let m = cmd.try_get_matches_from_mut(
275 ///     ["cmd", "--hostname", "rust-lang.org"]
276 /// ).unwrap();
277 ///
278 /// let hostname: &String = m.get_one("hostname")
279 ///     .expect("required");
280 /// assert_eq!(hostname, "rust-lang.org");
281 /// ```
282 impl<P> From<P> for ValueParser
283 where
284     P: TypedValueParser + Send + Sync + 'static,
285 {
from(p: P) -> Self286     fn from(p: P) -> Self {
287         Self::new(p)
288     }
289 }
290 
291 impl From<_AnonymousValueParser> for ValueParser {
from(p: _AnonymousValueParser) -> Self292     fn from(p: _AnonymousValueParser) -> Self {
293         p.0
294     }
295 }
296 
297 /// Create an `i64` [`ValueParser`] from a `N..M` range
298 ///
299 /// See [`RangedI64ValueParser`] for more control over the output type.
300 ///
301 /// See also [`RangedU64ValueParser`]
302 ///
303 /// # Examples
304 ///
305 /// ```rust
306 /// let mut cmd = clap::Command::new("raw")
307 ///     .arg(
308 ///         clap::Arg::new("port")
309 ///             .long("port")
310 ///             .value_parser(3000..4000)
311 ///             .action(clap::ArgAction::Set)
312 ///             .required(true)
313 ///     );
314 ///
315 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
316 /// let port: i64 = *m.get_one("port")
317 ///     .expect("required");
318 /// assert_eq!(port, 3001);
319 /// ```
320 impl From<std::ops::Range<i64>> for ValueParser {
from(value: std::ops::Range<i64>) -> Self321     fn from(value: std::ops::Range<i64>) -> Self {
322         let inner = RangedI64ValueParser::<i64>::new().range(value.start..value.end);
323         Self::from(inner)
324     }
325 }
326 
327 /// Create an `i64` [`ValueParser`] from a `N..=M` range
328 ///
329 /// See [`RangedI64ValueParser`] for more control over the output type.
330 ///
331 /// See also [`RangedU64ValueParser`]
332 ///
333 /// # Examples
334 ///
335 /// ```rust
336 /// let mut cmd = clap::Command::new("raw")
337 ///     .arg(
338 ///         clap::Arg::new("port")
339 ///             .long("port")
340 ///             .value_parser(3000..=4000)
341 ///             .action(clap::ArgAction::Set)
342 ///             .required(true)
343 ///     );
344 ///
345 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
346 /// let port: i64 = *m.get_one("port")
347 ///     .expect("required");
348 /// assert_eq!(port, 3001);
349 /// ```
350 impl From<std::ops::RangeInclusive<i64>> for ValueParser {
from(value: std::ops::RangeInclusive<i64>) -> Self351     fn from(value: std::ops::RangeInclusive<i64>) -> Self {
352         let inner = RangedI64ValueParser::<i64>::new().range(value.start()..=value.end());
353         Self::from(inner)
354     }
355 }
356 
357 /// Create an `i64` [`ValueParser`] from a `N..` range
358 ///
359 /// See [`RangedI64ValueParser`] for more control over the output type.
360 ///
361 /// See also [`RangedU64ValueParser`]
362 ///
363 /// # Examples
364 ///
365 /// ```rust
366 /// let mut cmd = clap::Command::new("raw")
367 ///     .arg(
368 ///         clap::Arg::new("port")
369 ///             .long("port")
370 ///             .value_parser(3000..)
371 ///             .action(clap::ArgAction::Set)
372 ///             .required(true)
373 ///     );
374 ///
375 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
376 /// let port: i64 = *m.get_one("port")
377 ///     .expect("required");
378 /// assert_eq!(port, 3001);
379 /// ```
380 impl From<std::ops::RangeFrom<i64>> for ValueParser {
from(value: std::ops::RangeFrom<i64>) -> Self381     fn from(value: std::ops::RangeFrom<i64>) -> Self {
382         let inner = RangedI64ValueParser::<i64>::new().range(value.start..);
383         Self::from(inner)
384     }
385 }
386 
387 /// Create an `i64` [`ValueParser`] from a `..M` range
388 ///
389 /// See [`RangedI64ValueParser`] for more control over the output type.
390 ///
391 /// See also [`RangedU64ValueParser`]
392 ///
393 /// # Examples
394 ///
395 /// ```rust
396 /// let mut cmd = clap::Command::new("raw")
397 ///     .arg(
398 ///         clap::Arg::new("port")
399 ///             .long("port")
400 ///             .value_parser(..3000)
401 ///             .action(clap::ArgAction::Set)
402 ///             .required(true)
403 ///     );
404 ///
405 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "80"]).unwrap();
406 /// let port: i64 = *m.get_one("port")
407 ///     .expect("required");
408 /// assert_eq!(port, 80);
409 /// ```
410 impl From<std::ops::RangeTo<i64>> for ValueParser {
from(value: std::ops::RangeTo<i64>) -> Self411     fn from(value: std::ops::RangeTo<i64>) -> Self {
412         let inner = RangedI64ValueParser::<i64>::new().range(..value.end);
413         Self::from(inner)
414     }
415 }
416 
417 /// Create an `i64` [`ValueParser`] from a `..=M` range
418 ///
419 /// See [`RangedI64ValueParser`] for more control over the output type.
420 ///
421 /// See also [`RangedU64ValueParser`]
422 ///
423 /// # Examples
424 ///
425 /// ```rust
426 /// let mut cmd = clap::Command::new("raw")
427 ///     .arg(
428 ///         clap::Arg::new("port")
429 ///             .long("port")
430 ///             .value_parser(..=3000)
431 ///             .action(clap::ArgAction::Set)
432 ///             .required(true)
433 ///     );
434 ///
435 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "80"]).unwrap();
436 /// let port: i64 = *m.get_one("port")
437 ///     .expect("required");
438 /// assert_eq!(port, 80);
439 /// ```
440 impl From<std::ops::RangeToInclusive<i64>> for ValueParser {
from(value: std::ops::RangeToInclusive<i64>) -> Self441     fn from(value: std::ops::RangeToInclusive<i64>) -> Self {
442         let inner = RangedI64ValueParser::<i64>::new().range(..=value.end);
443         Self::from(inner)
444     }
445 }
446 
447 /// Create an `i64` [`ValueParser`] from a `..` range
448 ///
449 /// See [`RangedI64ValueParser`] for more control over the output type.
450 ///
451 /// See also [`RangedU64ValueParser`]
452 ///
453 /// # Examples
454 ///
455 /// ```rust
456 /// let mut cmd = clap::Command::new("raw")
457 ///     .arg(
458 ///         clap::Arg::new("port")
459 ///             .long("port")
460 ///             .value_parser(..)
461 ///             .action(clap::ArgAction::Set)
462 ///             .required(true)
463 ///     );
464 ///
465 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
466 /// let port: i64 = *m.get_one("port")
467 ///     .expect("required");
468 /// assert_eq!(port, 3001);
469 /// ```
470 impl From<std::ops::RangeFull> for ValueParser {
from(value: std::ops::RangeFull) -> Self471     fn from(value: std::ops::RangeFull) -> Self {
472         let inner = RangedI64ValueParser::<i64>::new().range(value);
473         Self::from(inner)
474     }
475 }
476 
477 /// Create a [`ValueParser`] with [`PossibleValuesParser`]
478 ///
479 /// See [`PossibleValuesParser`] for more flexibility in creating the
480 /// [`PossibleValue`][crate::builder::PossibleValue]s.
481 ///
482 /// # Examples
483 ///
484 /// ```rust
485 /// let mut cmd = clap::Command::new("raw")
486 ///     .arg(
487 ///         clap::Arg::new("color")
488 ///             .long("color")
489 ///             .value_parser(["always", "auto", "never"])
490 ///             .default_value("auto")
491 ///     );
492 ///
493 /// let m = cmd.try_get_matches_from_mut(
494 ///     ["cmd", "--color", "never"]
495 /// ).unwrap();
496 ///
497 /// let color: &String = m.get_one("color")
498 ///     .expect("default");
499 /// assert_eq!(color, "never");
500 /// ```
501 impl<P, const C: usize> From<[P; C]> for ValueParser
502 where
503     P: Into<super::PossibleValue>,
504 {
from(values: [P; C]) -> Self505     fn from(values: [P; C]) -> Self {
506         let inner = PossibleValuesParser::from(values);
507         Self::from(inner)
508     }
509 }
510 
511 /// Create a [`ValueParser`] with [`PossibleValuesParser`]
512 ///
513 /// See [`PossibleValuesParser`] for more flexibility in creating the
514 /// [`PossibleValue`][crate::builder::PossibleValue]s.
515 ///
516 /// # Examples
517 ///
518 /// ```rust
519 /// let possible = vec!["always", "auto", "never"];
520 /// let mut cmd = clap::Command::new("raw")
521 ///     .arg(
522 ///         clap::Arg::new("color")
523 ///             .long("color")
524 ///             .value_parser(possible)
525 ///             .default_value("auto")
526 ///     );
527 ///
528 /// let m = cmd.try_get_matches_from_mut(
529 ///     ["cmd", "--color", "never"]
530 /// ).unwrap();
531 ///
532 /// let color: &String = m.get_one("color")
533 ///     .expect("default");
534 /// assert_eq!(color, "never");
535 /// ```
536 impl<P> From<Vec<P>> for ValueParser
537 where
538     P: Into<super::PossibleValue>,
539 {
from(values: Vec<P>) -> Self540     fn from(values: Vec<P>) -> Self {
541         let inner = PossibleValuesParser::from(values);
542         Self::from(inner)
543     }
544 }
545 
546 impl std::fmt::Debug for ValueParser {
fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error>547     fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
548         match &self.0 {
549             ValueParserInner::Bool => f.debug_struct("ValueParser::bool").finish(),
550             ValueParserInner::String => f.debug_struct("ValueParser::string").finish(),
551             ValueParserInner::OsString => f.debug_struct("ValueParser::os_string").finish(),
552             ValueParserInner::PathBuf => f.debug_struct("ValueParser::path_buf").finish(),
553             ValueParserInner::Other(o) => write!(f, "ValueParser::other({:?})", o.type_id()),
554         }
555     }
556 }
557 
558 impl Clone for ValueParser {
clone(&self) -> Self559     fn clone(&self) -> Self {
560         Self(match &self.0 {
561             ValueParserInner::Bool => ValueParserInner::Bool,
562             ValueParserInner::String => ValueParserInner::String,
563             ValueParserInner::OsString => ValueParserInner::OsString,
564             ValueParserInner::PathBuf => ValueParserInner::PathBuf,
565             ValueParserInner::Other(o) => ValueParserInner::Other(o.clone_any()),
566         })
567     }
568 }
569 
570 /// A type-erased wrapper for [`TypedValueParser`].
571 trait AnyValueParser: Send + Sync + 'static {
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<AnyValue, crate::Error>572     fn parse_ref(
573         &self,
574         cmd: &crate::Command,
575         arg: Option<&crate::Arg>,
576         value: &std::ffi::OsStr,
577     ) -> Result<AnyValue, crate::Error>;
578 
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<AnyValue, crate::Error>579     fn parse(
580         &self,
581         cmd: &crate::Command,
582         arg: Option<&crate::Arg>,
583         value: std::ffi::OsString,
584     ) -> Result<AnyValue, crate::Error>;
585 
586     /// Describes the content of `AnyValue`
type_id(&self) -> AnyValueId587     fn type_id(&self) -> AnyValueId;
588 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>589     fn possible_values(
590         &self,
591     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>;
592 
clone_any(&self) -> Box<dyn AnyValueParser>593     fn clone_any(&self) -> Box<dyn AnyValueParser>;
594 }
595 
596 impl<T, P> AnyValueParser for P
597 where
598     T: std::any::Any + Clone + Send + Sync + 'static,
599     P: TypedValueParser<Value = T>,
600 {
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<AnyValue, crate::Error>601     fn parse_ref(
602         &self,
603         cmd: &crate::Command,
604         arg: Option<&crate::Arg>,
605         value: &std::ffi::OsStr,
606     ) -> Result<AnyValue, crate::Error> {
607         let value = ok!(TypedValueParser::parse_ref(self, cmd, arg, value));
608         Ok(AnyValue::new(value))
609     }
610 
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<AnyValue, crate::Error>611     fn parse(
612         &self,
613         cmd: &crate::Command,
614         arg: Option<&crate::Arg>,
615         value: std::ffi::OsString,
616     ) -> Result<AnyValue, crate::Error> {
617         let value = ok!(TypedValueParser::parse(self, cmd, arg, value));
618         Ok(AnyValue::new(value))
619     }
620 
type_id(&self) -> AnyValueId621     fn type_id(&self) -> AnyValueId {
622         AnyValueId::of::<T>()
623     }
624 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>625     fn possible_values(
626         &self,
627     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
628         P::possible_values(self)
629     }
630 
clone_any(&self) -> Box<dyn AnyValueParser>631     fn clone_any(&self) -> Box<dyn AnyValueParser> {
632         Box::new(self.clone())
633     }
634 }
635 
636 /// Parse/validate argument values
637 ///
638 /// As alternatives to implementing `TypedValueParser`,
639 /// - Use `Fn(&str) -> Result<T, E>` which implements `TypedValueParser`
640 /// - [`TypedValueParser::map`] or [`TypedValueParser::try_map`] to adapt an existing `TypedValueParser`
641 ///
642 /// See `ValueParserFactory` to register `TypedValueParser::Value` with
643 /// [`value_parser!`][crate::value_parser].
644 ///
645 /// # Example
646 ///
647 #[cfg_attr(not(feature = "error-context"), doc = " ```ignore")]
648 #[cfg_attr(feature = "error-context", doc = " ```")]
649 /// # use clap::error::ErrorKind;
650 /// # use clap::error::ContextKind;
651 /// # use clap::error::ContextValue;
652 /// #[derive(Clone)]
653 /// struct Custom(u32);
654 ///
655 /// #[derive(Clone)]
656 /// struct CustomValueParser;
657 ///
658 /// impl clap::builder::TypedValueParser for CustomValueParser {
659 ///     type Value = Custom;
660 ///
661 ///     fn parse_ref(
662 ///         &self,
663 ///         cmd: &clap::Command,
664 ///         arg: Option<&clap::Arg>,
665 ///         value: &std::ffi::OsStr,
666 ///     ) -> Result<Self::Value, clap::Error> {
667 ///         let inner = clap::value_parser!(u32);
668 ///         let val = inner.parse_ref(cmd, arg, value)?;
669 ///
670 ///         const INVALID_VALUE: u32 = 10;
671 ///         if val == INVALID_VALUE {
672 ///             let mut err = clap::Error::new(ErrorKind::ValueValidation)
673 ///                 .with_cmd(cmd);
674 ///             if let Some(arg) = arg {
675 ///                 err.insert(ContextKind::InvalidArg, ContextValue::String(arg.to_string()));
676 ///             }
677 ///             err.insert(ContextKind::InvalidValue, ContextValue::String(INVALID_VALUE.to_string()));
678 ///             return Err(err);
679 ///         }
680 ///
681 ///         Ok(Custom(val))
682 ///     }
683 /// }
684 /// ```
685 pub trait TypedValueParser: Clone + Send + Sync + 'static {
686     /// Argument's value type
687     type Value: Send + Sync + Clone;
688 
689     /// Parse the argument value
690     ///
691     /// When `arg` is `None`, an external subcommand value is being parsed.
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>692     fn parse_ref(
693         &self,
694         cmd: &crate::Command,
695         arg: Option<&crate::Arg>,
696         value: &std::ffi::OsStr,
697     ) -> Result<Self::Value, crate::Error>;
698 
699     /// Parse the argument value
700     ///
701     /// When `arg` is `None`, an external subcommand value is being parsed.
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<Self::Value, crate::Error>702     fn parse(
703         &self,
704         cmd: &crate::Command,
705         arg: Option<&crate::Arg>,
706         value: std::ffi::OsString,
707     ) -> Result<Self::Value, crate::Error> {
708         self.parse_ref(cmd, arg, &value)
709     }
710 
711     /// Reflect on enumerated value properties
712     ///
713     /// Error checking should not be done with this; it is mostly targeted at user-facing
714     /// applications like errors and completion.
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>715     fn possible_values(
716         &self,
717     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
718         None
719     }
720 
721     /// Adapt a `TypedValueParser` from one value to another
722     ///
723     /// # Example
724     ///
725     /// ```rust
726     /// # use clap::Command;
727     /// # use clap::Arg;
728     /// # use clap::builder::TypedValueParser as _;
729     /// # use clap::builder::BoolishValueParser;
730     /// let cmd = Command::new("mycmd")
731     ///     .arg(
732     ///         Arg::new("flag")
733     ///             .long("flag")
734     ///             .action(clap::ArgAction::SetTrue)
735     ///             .value_parser(
736     ///                 BoolishValueParser::new()
737     ///                 .map(|b| -> usize {
738     ///                     if b { 10 } else { 5 }
739     ///                 })
740     ///             )
741     ///     );
742     ///
743     /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
744     /// assert!(matches.contains_id("flag"));
745     /// assert_eq!(
746     ///     matches.get_one::<usize>("flag").copied(),
747     ///     Some(10)
748     /// );
749     ///
750     /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap();
751     /// assert!(matches.contains_id("flag"));
752     /// assert_eq!(
753     ///     matches.get_one::<usize>("flag").copied(),
754     ///     Some(5)
755     /// );
756     /// ```
map<T, F>(self, func: F) -> MapValueParser<Self, F> where T: Send + Sync + Clone, F: Fn(Self::Value) -> T + Clone,757     fn map<T, F>(self, func: F) -> MapValueParser<Self, F>
758     where
759         T: Send + Sync + Clone,
760         F: Fn(Self::Value) -> T + Clone,
761     {
762         MapValueParser::new(self, func)
763     }
764 
765     /// Adapt a `TypedValueParser` from one value to another
766     ///
767     /// # Example
768     ///
769     /// ```rust
770     /// # use std::ffi::OsString;
771     /// # use std::ffi::OsStr;
772     /// # use std::path::PathBuf;
773     /// # use std::path::Path;
774     /// # use clap::Command;
775     /// # use clap::Arg;
776     /// # use clap::builder::TypedValueParser as _;
777     /// # use clap::builder::OsStringValueParser;
778     /// let cmd = Command::new("mycmd")
779     ///     .arg(
780     ///         Arg::new("flag")
781     ///             .long("flag")
782     ///             .value_parser(
783     ///                 OsStringValueParser::new()
784     ///                 .try_map(verify_ext)
785     ///             )
786     ///     );
787     ///
788     /// fn verify_ext(os: OsString) -> Result<PathBuf, &'static str> {
789     ///     let path = PathBuf::from(os);
790     ///     if path.extension() != Some(OsStr::new("rs")) {
791     ///         return Err("only Rust files are supported");
792     ///     }
793     ///     Ok(path)
794     /// }
795     ///
796     /// let error = cmd.clone().try_get_matches_from(["mycmd", "--flag", "foo.txt"]).unwrap_err();
797     /// error.print();
798     ///
799     /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "foo.rs"]).unwrap();
800     /// assert!(matches.contains_id("flag"));
801     /// assert_eq!(
802     ///     matches.get_one::<PathBuf>("flag").map(|s| s.as_path()),
803     ///     Some(Path::new("foo.rs"))
804     /// );
805     /// ```
try_map<T, E, F>(self, func: F) -> TryMapValueParser<Self, F> where F: Fn(Self::Value) -> Result<T, E> + Clone + Send + Sync + 'static, T: Send + Sync + Clone, E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,806     fn try_map<T, E, F>(self, func: F) -> TryMapValueParser<Self, F>
807     where
808         F: Fn(Self::Value) -> Result<T, E> + Clone + Send + Sync + 'static,
809         T: Send + Sync + Clone,
810         E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
811     {
812         TryMapValueParser::new(self, func)
813     }
814 }
815 
816 impl<F, T, E> TypedValueParser for F
817 where
818     F: Fn(&str) -> Result<T, E> + Clone + Send + Sync + 'static,
819     E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
820     T: Send + Sync + Clone,
821 {
822     type Value = T;
823 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>824     fn parse_ref(
825         &self,
826         cmd: &crate::Command,
827         arg: Option<&crate::Arg>,
828         value: &std::ffi::OsStr,
829     ) -> Result<Self::Value, crate::Error> {
830         let value = ok!(value.to_str().ok_or_else(|| {
831             crate::Error::invalid_utf8(
832                 cmd,
833                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
834             )
835         }));
836         let value = ok!((self)(value).map_err(|e| {
837             let arg = arg
838                 .map(|a| a.to_string())
839                 .unwrap_or_else(|| "...".to_owned());
840             crate::Error::value_validation(arg, value.to_owned(), e.into()).with_cmd(cmd)
841         }));
842         Ok(value)
843     }
844 }
845 
846 /// Implementation for [`ValueParser::string`]
847 ///
848 /// Useful for composing new [`TypedValueParser`]s
849 #[derive(Copy, Clone, Debug)]
850 #[non_exhaustive]
851 pub struct StringValueParser {}
852 
853 impl StringValueParser {
854     /// Implementation for [`ValueParser::string`]
new() -> Self855     pub fn new() -> Self {
856         Self {}
857     }
858 }
859 
860 impl TypedValueParser for StringValueParser {
861     type Value = String;
862 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>863     fn parse_ref(
864         &self,
865         cmd: &crate::Command,
866         arg: Option<&crate::Arg>,
867         value: &std::ffi::OsStr,
868     ) -> Result<Self::Value, crate::Error> {
869         TypedValueParser::parse(self, cmd, arg, value.to_owned())
870     }
871 
parse( &self, cmd: &crate::Command, _arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<Self::Value, crate::Error>872     fn parse(
873         &self,
874         cmd: &crate::Command,
875         _arg: Option<&crate::Arg>,
876         value: std::ffi::OsString,
877     ) -> Result<Self::Value, crate::Error> {
878         let value = ok!(value.into_string().map_err(|_| {
879             crate::Error::invalid_utf8(
880                 cmd,
881                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
882             )
883         }));
884         Ok(value)
885     }
886 }
887 
888 impl Default for StringValueParser {
default() -> Self889     fn default() -> Self {
890         Self::new()
891     }
892 }
893 
894 /// Implementation for [`ValueParser::os_string`]
895 ///
896 /// Useful for composing new [`TypedValueParser`]s
897 #[derive(Copy, Clone, Debug)]
898 #[non_exhaustive]
899 pub struct OsStringValueParser {}
900 
901 impl OsStringValueParser {
902     /// Implementation for [`ValueParser::os_string`]
new() -> Self903     pub fn new() -> Self {
904         Self {}
905     }
906 }
907 
908 impl TypedValueParser for OsStringValueParser {
909     type Value = std::ffi::OsString;
910 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>911     fn parse_ref(
912         &self,
913         cmd: &crate::Command,
914         arg: Option<&crate::Arg>,
915         value: &std::ffi::OsStr,
916     ) -> Result<Self::Value, crate::Error> {
917         TypedValueParser::parse(self, cmd, arg, value.to_owned())
918     }
919 
parse( &self, _cmd: &crate::Command, _arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<Self::Value, crate::Error>920     fn parse(
921         &self,
922         _cmd: &crate::Command,
923         _arg: Option<&crate::Arg>,
924         value: std::ffi::OsString,
925     ) -> Result<Self::Value, crate::Error> {
926         Ok(value)
927     }
928 }
929 
930 impl Default for OsStringValueParser {
default() -> Self931     fn default() -> Self {
932         Self::new()
933     }
934 }
935 
936 /// Implementation for [`ValueParser::path_buf`]
937 ///
938 /// Useful for composing new [`TypedValueParser`]s
939 #[derive(Copy, Clone, Debug)]
940 #[non_exhaustive]
941 pub struct PathBufValueParser {}
942 
943 impl PathBufValueParser {
944     /// Implementation for [`ValueParser::path_buf`]
new() -> Self945     pub fn new() -> Self {
946         Self {}
947     }
948 }
949 
950 impl TypedValueParser for PathBufValueParser {
951     type Value = std::path::PathBuf;
952 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>953     fn parse_ref(
954         &self,
955         cmd: &crate::Command,
956         arg: Option<&crate::Arg>,
957         value: &std::ffi::OsStr,
958     ) -> Result<Self::Value, crate::Error> {
959         TypedValueParser::parse(self, cmd, arg, value.to_owned())
960     }
961 
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<Self::Value, crate::Error>962     fn parse(
963         &self,
964         cmd: &crate::Command,
965         arg: Option<&crate::Arg>,
966         value: std::ffi::OsString,
967     ) -> Result<Self::Value, crate::Error> {
968         if value.is_empty() {
969             return Err(crate::Error::empty_value(
970                 cmd,
971                 &[],
972                 arg.map(ToString::to_string)
973                     .unwrap_or_else(|| "...".to_owned()),
974             ));
975         }
976         Ok(Self::Value::from(value))
977     }
978 }
979 
980 impl Default for PathBufValueParser {
default() -> Self981     fn default() -> Self {
982         Self::new()
983     }
984 }
985 
986 /// Parse an [`ValueEnum`][crate::ValueEnum] value.
987 ///
988 /// See also:
989 /// - [`PossibleValuesParser`]
990 ///
991 /// # Example
992 ///
993 /// ```rust
994 /// # use std::ffi::OsStr;
995 /// # use clap::ColorChoice;
996 /// # use clap::builder::TypedValueParser;
997 /// # let cmd = clap::Command::new("test");
998 /// # let arg = None;
999 ///
1000 /// // Usage
1001 /// let mut cmd = clap::Command::new("raw")
1002 ///     .arg(
1003 ///         clap::Arg::new("color")
1004 ///             .value_parser(clap::builder::EnumValueParser::<ColorChoice>::new())
1005 ///             .required(true)
1006 ///     );
1007 ///
1008 /// let m = cmd.try_get_matches_from_mut(["cmd", "always"]).unwrap();
1009 /// let port: ColorChoice = *m.get_one("color")
1010 ///     .expect("required");
1011 /// assert_eq!(port, ColorChoice::Always);
1012 ///
1013 /// // Semantics
1014 /// let value_parser = clap::builder::EnumValueParser::<ColorChoice>::new();
1015 /// // or
1016 /// let value_parser = clap::value_parser!(ColorChoice);
1017 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
1018 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1019 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("always")).unwrap(), ColorChoice::Always);
1020 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("auto")).unwrap(), ColorChoice::Auto);
1021 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("never")).unwrap(), ColorChoice::Never);
1022 /// ```
1023 #[derive(Clone, Debug)]
1024 pub struct EnumValueParser<E: crate::ValueEnum + Clone + Send + Sync + 'static>(
1025     std::marker::PhantomData<E>,
1026 );
1027 
1028 impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> EnumValueParser<E> {
1029     /// Parse an [`ValueEnum`][crate::ValueEnum]
new() -> Self1030     pub fn new() -> Self {
1031         let phantom: std::marker::PhantomData<E> = Default::default();
1032         Self(phantom)
1033     }
1034 }
1035 
1036 impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> TypedValueParser for EnumValueParser<E> {
1037     type Value = E;
1038 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1039     fn parse_ref(
1040         &self,
1041         cmd: &crate::Command,
1042         arg: Option<&crate::Arg>,
1043         value: &std::ffi::OsStr,
1044     ) -> Result<Self::Value, crate::Error> {
1045         let ignore_case = arg.map(|a| a.is_ignore_case_set()).unwrap_or(false);
1046         let possible_vals = || {
1047             E::value_variants()
1048                 .iter()
1049                 .filter_map(|v| v.to_possible_value())
1050                 .filter(|v| !v.is_hide_set())
1051                 .map(|v| v.get_name().to_owned())
1052                 .collect::<Vec<_>>()
1053         };
1054 
1055         let value = ok!(value.to_str().ok_or_else(|| {
1056             crate::Error::invalid_value(
1057                 cmd,
1058                 value.to_string_lossy().into_owned(),
1059                 &possible_vals(),
1060                 arg.map(ToString::to_string)
1061                     .unwrap_or_else(|| "...".to_owned()),
1062             )
1063         }));
1064         let value = ok!(E::value_variants()
1065             .iter()
1066             .find(|v| {
1067                 v.to_possible_value()
1068                     .expect("ValueEnum::value_variants contains only values with a corresponding ValueEnum::to_possible_value")
1069                     .matches(value, ignore_case)
1070             })
1071             .ok_or_else(|| {
1072             crate::Error::invalid_value(
1073                 cmd,
1074                 value.to_owned(),
1075                 &possible_vals(),
1076                 arg.map(ToString::to_string)
1077                     .unwrap_or_else(|| "...".to_owned()),
1078             )
1079             }))
1080             .clone();
1081         Ok(value)
1082     }
1083 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>1084     fn possible_values(
1085         &self,
1086     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
1087         Some(Box::new(
1088             E::value_variants()
1089                 .iter()
1090                 .filter_map(|v| v.to_possible_value()),
1091         ))
1092     }
1093 }
1094 
1095 impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> Default for EnumValueParser<E> {
default() -> Self1096     fn default() -> Self {
1097         Self::new()
1098     }
1099 }
1100 
1101 /// Verify the value is from an enumerated set of [`PossibleValue`][crate::builder::PossibleValue].
1102 ///
1103 /// See also:
1104 /// - [`EnumValueParser`] for directly supporting [`ValueEnum`][crate::ValueEnum] types
1105 /// - [`TypedValueParser::map`] for adapting values to a more specialized type, like an external
1106 ///   enums that can't implement [`ValueEnum`][crate::ValueEnum]
1107 ///
1108 /// # Example
1109 ///
1110 /// Usage:
1111 /// ```rust
1112 /// let mut cmd = clap::Command::new("raw")
1113 ///     .arg(
1114 ///         clap::Arg::new("color")
1115 ///             .value_parser(clap::builder::PossibleValuesParser::new(["always", "auto", "never"]))
1116 ///             .required(true)
1117 ///     );
1118 ///
1119 /// let m = cmd.try_get_matches_from_mut(["cmd", "always"]).unwrap();
1120 /// let port: &String = m.get_one("color")
1121 ///     .expect("required");
1122 /// assert_eq!(port, "always");
1123 /// ```
1124 ///
1125 /// Semantics:
1126 /// ```rust
1127 /// # use std::ffi::OsStr;
1128 /// # use clap::builder::TypedValueParser;
1129 /// # let cmd = clap::Command::new("test");
1130 /// # let arg = None;
1131 /// let value_parser = clap::builder::PossibleValuesParser::new(["always", "auto", "never"]);
1132 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
1133 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1134 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("always")).unwrap(), "always");
1135 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("auto")).unwrap(), "auto");
1136 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("never")).unwrap(), "never");
1137 /// ```
1138 #[derive(Clone, Debug)]
1139 pub struct PossibleValuesParser(Vec<super::PossibleValue>);
1140 
1141 impl PossibleValuesParser {
1142     /// Verify the value is from an enumerated set pf [`PossibleValue`][crate::builder::PossibleValue].
new(values: impl Into<PossibleValuesParser>) -> Self1143     pub fn new(values: impl Into<PossibleValuesParser>) -> Self {
1144         values.into()
1145     }
1146 }
1147 
1148 impl TypedValueParser for PossibleValuesParser {
1149     type Value = String;
1150 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1151     fn parse_ref(
1152         &self,
1153         cmd: &crate::Command,
1154         arg: Option<&crate::Arg>,
1155         value: &std::ffi::OsStr,
1156     ) -> Result<Self::Value, crate::Error> {
1157         TypedValueParser::parse(self, cmd, arg, value.to_owned())
1158     }
1159 
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<String, crate::Error>1160     fn parse(
1161         &self,
1162         cmd: &crate::Command,
1163         arg: Option<&crate::Arg>,
1164         value: std::ffi::OsString,
1165     ) -> Result<String, crate::Error> {
1166         let value = ok!(value.into_string().map_err(|_| {
1167             crate::Error::invalid_utf8(
1168                 cmd,
1169                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1170             )
1171         }));
1172 
1173         let ignore_case = arg.map(|a| a.is_ignore_case_set()).unwrap_or(false);
1174         if self.0.iter().any(|v| v.matches(&value, ignore_case)) {
1175             Ok(value)
1176         } else {
1177             let possible_vals = self
1178                 .0
1179                 .iter()
1180                 .filter(|v| !v.is_hide_set())
1181                 .map(|v| v.get_name().to_owned())
1182                 .collect::<Vec<_>>();
1183 
1184             Err(crate::Error::invalid_value(
1185                 cmd,
1186                 value,
1187                 &possible_vals,
1188                 arg.map(ToString::to_string)
1189                     .unwrap_or_else(|| "...".to_owned()),
1190             ))
1191         }
1192     }
1193 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>1194     fn possible_values(
1195         &self,
1196     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
1197         Some(Box::new(self.0.iter().cloned()))
1198     }
1199 }
1200 
1201 impl<I, T> From<I> for PossibleValuesParser
1202 where
1203     I: IntoIterator<Item = T>,
1204     T: Into<super::PossibleValue>,
1205 {
from(values: I) -> Self1206     fn from(values: I) -> Self {
1207         Self(values.into_iter().map(|t| t.into()).collect())
1208     }
1209 }
1210 
1211 /// Parse number that fall within a range of values
1212 ///
1213 /// **NOTE:** To capture negative values, you will also need to set
1214 /// [`Arg::allow_negative_numbers`][crate::Arg::allow_negative_numbers] or
1215 /// [`Arg::allow_hyphen_values`][crate::Arg::allow_hyphen_values].
1216 ///
1217 /// # Example
1218 ///
1219 /// Usage:
1220 /// ```rust
1221 /// let mut cmd = clap::Command::new("raw")
1222 ///     .arg(
1223 ///         clap::Arg::new("port")
1224 ///             .long("port")
1225 ///             .value_parser(clap::value_parser!(u16).range(3000..))
1226 ///             .action(clap::ArgAction::Set)
1227 ///             .required(true)
1228 ///     );
1229 ///
1230 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
1231 /// let port: u16 = *m.get_one("port")
1232 ///     .expect("required");
1233 /// assert_eq!(port, 3001);
1234 /// ```
1235 ///
1236 /// Semantics:
1237 /// ```rust
1238 /// # use std::ffi::OsStr;
1239 /// # use clap::builder::TypedValueParser;
1240 /// # let cmd = clap::Command::new("test");
1241 /// # let arg = None;
1242 /// let value_parser = clap::builder::RangedI64ValueParser::<i32>::new().range(-1..200);
1243 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
1244 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1245 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("-200")).is_err());
1246 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("300")).is_err());
1247 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("-1")).unwrap(), -1);
1248 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), 0);
1249 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("50")).unwrap(), 50);
1250 /// ```
1251 #[derive(Copy, Clone, Debug)]
1252 pub struct RangedI64ValueParser<T: std::convert::TryFrom<i64> + Clone + Send + Sync = i64> {
1253     bounds: (std::ops::Bound<i64>, std::ops::Bound<i64>),
1254     target: std::marker::PhantomData<T>,
1255 }
1256 
1257 impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> RangedI64ValueParser<T> {
1258     /// Select full range of `i64`
new() -> Self1259     pub fn new() -> Self {
1260         Self::from(..)
1261     }
1262 
1263     /// Narrow the supported range
range<B: RangeBounds<i64>>(mut self, range: B) -> Self1264     pub fn range<B: RangeBounds<i64>>(mut self, range: B) -> Self {
1265         // Consideration: when the user does `value_parser!(u8).range()`
1266         // - Avoid programming mistakes by accidentally expanding the range
1267         // - Make it convenient to limit the range like with `..10`
1268         let start = match range.start_bound() {
1269             l @ std::ops::Bound::Included(i) => {
1270                 debug_assert!(
1271                     self.bounds.contains(i),
1272                     "{} must be in {:?}",
1273                     i,
1274                     self.bounds
1275                 );
1276                 l.cloned()
1277             }
1278             l @ std::ops::Bound::Excluded(i) => {
1279                 debug_assert!(
1280                     self.bounds.contains(&i.saturating_add(1)),
1281                     "{} must be in {:?}",
1282                     i,
1283                     self.bounds
1284                 );
1285                 l.cloned()
1286             }
1287             std::ops::Bound::Unbounded => self.bounds.start_bound().cloned(),
1288         };
1289         let end = match range.end_bound() {
1290             l @ std::ops::Bound::Included(i) => {
1291                 debug_assert!(
1292                     self.bounds.contains(i),
1293                     "{} must be in {:?}",
1294                     i,
1295                     self.bounds
1296                 );
1297                 l.cloned()
1298             }
1299             l @ std::ops::Bound::Excluded(i) => {
1300                 debug_assert!(
1301                     self.bounds.contains(&i.saturating_sub(1)),
1302                     "{} must be in {:?}",
1303                     i,
1304                     self.bounds
1305                 );
1306                 l.cloned()
1307             }
1308             std::ops::Bound::Unbounded => self.bounds.end_bound().cloned(),
1309         };
1310         self.bounds = (start, end);
1311         self
1312     }
1313 
format_bounds(&self) -> String1314     fn format_bounds(&self) -> String {
1315         let mut result = match self.bounds.0 {
1316             std::ops::Bound::Included(i) => i.to_string(),
1317             std::ops::Bound::Excluded(i) => i.saturating_add(1).to_string(),
1318             std::ops::Bound::Unbounded => i64::MIN.to_string(),
1319         };
1320         result.push_str("..");
1321         match self.bounds.1 {
1322             std::ops::Bound::Included(i) => {
1323                 result.push('=');
1324                 result.push_str(&i.to_string());
1325             }
1326             std::ops::Bound::Excluded(i) => {
1327                 result.push_str(&i.to_string());
1328             }
1329             std::ops::Bound::Unbounded => {
1330                 result.push_str(&i64::MAX.to_string());
1331             }
1332         }
1333         result
1334     }
1335 }
1336 
1337 impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync + 'static> TypedValueParser
1338     for RangedI64ValueParser<T>
1339 where
1340     <T as std::convert::TryFrom<i64>>::Error: Send + Sync + 'static + std::error::Error + ToString,
1341 {
1342     type Value = T;
1343 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, raw_value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1344     fn parse_ref(
1345         &self,
1346         cmd: &crate::Command,
1347         arg: Option<&crate::Arg>,
1348         raw_value: &std::ffi::OsStr,
1349     ) -> Result<Self::Value, crate::Error> {
1350         let value = ok!(raw_value.to_str().ok_or_else(|| {
1351             crate::Error::invalid_utf8(
1352                 cmd,
1353                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1354             )
1355         }));
1356         let value = ok!(value.parse::<i64>().map_err(|err| {
1357             let arg = arg
1358                 .map(|a| a.to_string())
1359                 .unwrap_or_else(|| "...".to_owned());
1360             crate::Error::value_validation(
1361                 arg,
1362                 raw_value.to_string_lossy().into_owned(),
1363                 err.into(),
1364             )
1365             .with_cmd(cmd)
1366         }));
1367         if !self.bounds.contains(&value) {
1368             let arg = arg
1369                 .map(|a| a.to_string())
1370                 .unwrap_or_else(|| "...".to_owned());
1371             return Err(crate::Error::value_validation(
1372                 arg,
1373                 raw_value.to_string_lossy().into_owned(),
1374                 format!("{} is not in {}", value, self.format_bounds()).into(),
1375             )
1376             .with_cmd(cmd));
1377         }
1378 
1379         let value: Result<Self::Value, _> = value.try_into();
1380         let value = ok!(value.map_err(|err| {
1381             let arg = arg
1382                 .map(|a| a.to_string())
1383                 .unwrap_or_else(|| "...".to_owned());
1384             crate::Error::value_validation(
1385                 arg,
1386                 raw_value.to_string_lossy().into_owned(),
1387                 err.into(),
1388             )
1389             .with_cmd(cmd)
1390         }));
1391 
1392         Ok(value)
1393     }
1394 }
1395 
1396 impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync, B: RangeBounds<i64>> From<B>
1397     for RangedI64ValueParser<T>
1398 {
from(range: B) -> Self1399     fn from(range: B) -> Self {
1400         Self {
1401             bounds: (range.start_bound().cloned(), range.end_bound().cloned()),
1402             target: Default::default(),
1403         }
1404     }
1405 }
1406 
1407 impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> Default for RangedI64ValueParser<T> {
default() -> Self1408     fn default() -> Self {
1409         Self::new()
1410     }
1411 }
1412 
1413 /// Parse number that fall within a range of values
1414 ///
1415 /// # Example
1416 ///
1417 /// Usage:
1418 /// ```rust
1419 /// let mut cmd = clap::Command::new("raw")
1420 ///     .arg(
1421 ///         clap::Arg::new("port")
1422 ///             .long("port")
1423 ///             .value_parser(clap::value_parser!(u64).range(3000..))
1424 ///             .action(clap::ArgAction::Set)
1425 ///             .required(true)
1426 ///     );
1427 ///
1428 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
1429 /// let port: u64 = *m.get_one("port")
1430 ///     .expect("required");
1431 /// assert_eq!(port, 3001);
1432 /// ```
1433 ///
1434 /// Semantics:
1435 /// ```rust
1436 /// # use std::ffi::OsStr;
1437 /// # use clap::builder::TypedValueParser;
1438 /// # let cmd = clap::Command::new("test");
1439 /// # let arg = None;
1440 /// let value_parser = clap::builder::RangedU64ValueParser::<u32>::new().range(0..200);
1441 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
1442 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1443 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("-200")).is_err());
1444 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("300")).is_err());
1445 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("-1")).is_err());
1446 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), 0);
1447 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("50")).unwrap(), 50);
1448 /// ```
1449 #[derive(Copy, Clone, Debug)]
1450 pub struct RangedU64ValueParser<T: std::convert::TryFrom<u64> = u64> {
1451     bounds: (std::ops::Bound<u64>, std::ops::Bound<u64>),
1452     target: std::marker::PhantomData<T>,
1453 }
1454 
1455 impl<T: std::convert::TryFrom<u64>> RangedU64ValueParser<T> {
1456     /// Select full range of `u64`
new() -> Self1457     pub fn new() -> Self {
1458         Self::from(..)
1459     }
1460 
1461     /// Narrow the supported range
range<B: RangeBounds<u64>>(mut self, range: B) -> Self1462     pub fn range<B: RangeBounds<u64>>(mut self, range: B) -> Self {
1463         // Consideration: when the user does `value_parser!(u8).range()`
1464         // - Avoid programming mistakes by accidentally expanding the range
1465         // - Make it convenient to limit the range like with `..10`
1466         let start = match range.start_bound() {
1467             l @ std::ops::Bound::Included(i) => {
1468                 debug_assert!(
1469                     self.bounds.contains(i),
1470                     "{} must be in {:?}",
1471                     i,
1472                     self.bounds
1473                 );
1474                 l.cloned()
1475             }
1476             l @ std::ops::Bound::Excluded(i) => {
1477                 debug_assert!(
1478                     self.bounds.contains(&i.saturating_add(1)),
1479                     "{} must be in {:?}",
1480                     i,
1481                     self.bounds
1482                 );
1483                 l.cloned()
1484             }
1485             std::ops::Bound::Unbounded => self.bounds.start_bound().cloned(),
1486         };
1487         let end = match range.end_bound() {
1488             l @ std::ops::Bound::Included(i) => {
1489                 debug_assert!(
1490                     self.bounds.contains(i),
1491                     "{} must be in {:?}",
1492                     i,
1493                     self.bounds
1494                 );
1495                 l.cloned()
1496             }
1497             l @ std::ops::Bound::Excluded(i) => {
1498                 debug_assert!(
1499                     self.bounds.contains(&i.saturating_sub(1)),
1500                     "{} must be in {:?}",
1501                     i,
1502                     self.bounds
1503                 );
1504                 l.cloned()
1505             }
1506             std::ops::Bound::Unbounded => self.bounds.end_bound().cloned(),
1507         };
1508         self.bounds = (start, end);
1509         self
1510     }
1511 
format_bounds(&self) -> String1512     fn format_bounds(&self) -> String {
1513         let mut result = match self.bounds.0 {
1514             std::ops::Bound::Included(i) => i.to_string(),
1515             std::ops::Bound::Excluded(i) => i.saturating_add(1).to_string(),
1516             std::ops::Bound::Unbounded => u64::MIN.to_string(),
1517         };
1518         result.push_str("..");
1519         match self.bounds.1 {
1520             std::ops::Bound::Included(i) => {
1521                 result.push('=');
1522                 result.push_str(&i.to_string());
1523             }
1524             std::ops::Bound::Excluded(i) => {
1525                 result.push_str(&i.to_string());
1526             }
1527             std::ops::Bound::Unbounded => {
1528                 result.push_str(&u64::MAX.to_string());
1529             }
1530         }
1531         result
1532     }
1533 }
1534 
1535 impl<T: std::convert::TryFrom<u64> + Clone + Send + Sync + 'static> TypedValueParser
1536     for RangedU64ValueParser<T>
1537 where
1538     <T as std::convert::TryFrom<u64>>::Error: Send + Sync + 'static + std::error::Error + ToString,
1539 {
1540     type Value = T;
1541 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, raw_value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1542     fn parse_ref(
1543         &self,
1544         cmd: &crate::Command,
1545         arg: Option<&crate::Arg>,
1546         raw_value: &std::ffi::OsStr,
1547     ) -> Result<Self::Value, crate::Error> {
1548         let value = ok!(raw_value.to_str().ok_or_else(|| {
1549             crate::Error::invalid_utf8(
1550                 cmd,
1551                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1552             )
1553         }));
1554         let value = ok!(value.parse::<u64>().map_err(|err| {
1555             let arg = arg
1556                 .map(|a| a.to_string())
1557                 .unwrap_or_else(|| "...".to_owned());
1558             crate::Error::value_validation(
1559                 arg,
1560                 raw_value.to_string_lossy().into_owned(),
1561                 err.into(),
1562             )
1563             .with_cmd(cmd)
1564         }));
1565         if !self.bounds.contains(&value) {
1566             let arg = arg
1567                 .map(|a| a.to_string())
1568                 .unwrap_or_else(|| "...".to_owned());
1569             return Err(crate::Error::value_validation(
1570                 arg,
1571                 raw_value.to_string_lossy().into_owned(),
1572                 format!("{} is not in {}", value, self.format_bounds()).into(),
1573             )
1574             .with_cmd(cmd));
1575         }
1576 
1577         let value: Result<Self::Value, _> = value.try_into();
1578         let value = ok!(value.map_err(|err| {
1579             let arg = arg
1580                 .map(|a| a.to_string())
1581                 .unwrap_or_else(|| "...".to_owned());
1582             crate::Error::value_validation(
1583                 arg,
1584                 raw_value.to_string_lossy().into_owned(),
1585                 err.into(),
1586             )
1587             .with_cmd(cmd)
1588         }));
1589 
1590         Ok(value)
1591     }
1592 }
1593 
1594 impl<T: std::convert::TryFrom<u64>, B: RangeBounds<u64>> From<B> for RangedU64ValueParser<T> {
from(range: B) -> Self1595     fn from(range: B) -> Self {
1596         Self {
1597             bounds: (range.start_bound().cloned(), range.end_bound().cloned()),
1598             target: Default::default(),
1599         }
1600     }
1601 }
1602 
1603 impl<T: std::convert::TryFrom<u64>> Default for RangedU64ValueParser<T> {
default() -> Self1604     fn default() -> Self {
1605         Self::new()
1606     }
1607 }
1608 
1609 /// Implementation for [`ValueParser::bool`]
1610 ///
1611 /// Useful for composing new [`TypedValueParser`]s
1612 #[derive(Copy, Clone, Debug)]
1613 #[non_exhaustive]
1614 pub struct BoolValueParser {}
1615 
1616 impl BoolValueParser {
1617     /// Implementation for [`ValueParser::bool`]
new() -> Self1618     pub fn new() -> Self {
1619         Self {}
1620     }
1621 
possible_values() -> impl Iterator<Item = crate::builder::PossibleValue>1622     fn possible_values() -> impl Iterator<Item = crate::builder::PossibleValue> {
1623         ["true", "false"]
1624             .iter()
1625             .copied()
1626             .map(crate::builder::PossibleValue::new)
1627     }
1628 }
1629 
1630 impl TypedValueParser for BoolValueParser {
1631     type Value = bool;
1632 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1633     fn parse_ref(
1634         &self,
1635         cmd: &crate::Command,
1636         arg: Option<&crate::Arg>,
1637         value: &std::ffi::OsStr,
1638     ) -> Result<Self::Value, crate::Error> {
1639         let value = if value == std::ffi::OsStr::new("true") {
1640             true
1641         } else if value == std::ffi::OsStr::new("false") {
1642             false
1643         } else {
1644             // Intentionally showing hidden as we hide all of them
1645             let possible_vals = Self::possible_values()
1646                 .map(|v| v.get_name().to_owned())
1647                 .collect::<Vec<_>>();
1648 
1649             return Err(crate::Error::invalid_value(
1650                 cmd,
1651                 value.to_string_lossy().into_owned(),
1652                 &possible_vals,
1653                 arg.map(ToString::to_string)
1654                     .unwrap_or_else(|| "...".to_owned()),
1655             ));
1656         };
1657         Ok(value)
1658     }
1659 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>1660     fn possible_values(
1661         &self,
1662     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
1663         Some(Box::new(Self::possible_values()))
1664     }
1665 }
1666 
1667 impl Default for BoolValueParser {
default() -> Self1668     fn default() -> Self {
1669         Self::new()
1670     }
1671 }
1672 
1673 /// Parse false-like string values, everything else is `true`
1674 ///
1675 /// See also:
1676 /// - [`ValueParser::bool`] for assuming non-false is true
1677 /// - [`BoolishValueParser`] for different human readable bool representations
1678 ///
1679 /// # Example
1680 ///
1681 /// Usage:
1682 /// ```rust
1683 /// let mut cmd = clap::Command::new("raw")
1684 ///     .arg(
1685 ///         clap::Arg::new("append")
1686 ///             .value_parser(clap::builder::FalseyValueParser::new())
1687 ///             .required(true)
1688 ///     );
1689 ///
1690 /// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap();
1691 /// let port: bool = *m.get_one("append")
1692 ///     .expect("required");
1693 /// assert_eq!(port, true);
1694 /// ```
1695 ///
1696 /// Semantics:
1697 /// ```rust
1698 /// # use std::ffi::OsStr;
1699 /// # use clap::builder::TypedValueParser;
1700 /// # let cmd = clap::Command::new("test");
1701 /// # let arg = None;
1702 /// let value_parser = clap::builder::FalseyValueParser::new();
1703 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).unwrap(), true);
1704 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("100")).unwrap(), true);
1705 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).unwrap(), false);
1706 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("false")).unwrap(), false);
1707 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("No")).unwrap(), false);
1708 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("oFF")).unwrap(), false);
1709 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), false);
1710 /// ```
1711 #[derive(Copy, Clone, Debug)]
1712 #[non_exhaustive]
1713 pub struct FalseyValueParser {}
1714 
1715 impl FalseyValueParser {
1716     /// Parse false-like string values, everything else is `true`
new() -> Self1717     pub fn new() -> Self {
1718         Self {}
1719     }
1720 
possible_values() -> impl Iterator<Item = crate::builder::PossibleValue>1721     fn possible_values() -> impl Iterator<Item = crate::builder::PossibleValue> {
1722         crate::util::TRUE_LITERALS
1723             .iter()
1724             .chain(crate::util::FALSE_LITERALS.iter())
1725             .copied()
1726             .map(|l| crate::builder::PossibleValue::new(l).hide(l != "true" && l != "false"))
1727     }
1728 }
1729 
1730 impl TypedValueParser for FalseyValueParser {
1731     type Value = bool;
1732 
parse_ref( &self, cmd: &crate::Command, _arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1733     fn parse_ref(
1734         &self,
1735         cmd: &crate::Command,
1736         _arg: Option<&crate::Arg>,
1737         value: &std::ffi::OsStr,
1738     ) -> Result<Self::Value, crate::Error> {
1739         let value = ok!(value.to_str().ok_or_else(|| {
1740             crate::Error::invalid_utf8(
1741                 cmd,
1742                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1743             )
1744         }));
1745         let value = if value.is_empty() {
1746             false
1747         } else {
1748             crate::util::str_to_bool(value).unwrap_or(true)
1749         };
1750         Ok(value)
1751     }
1752 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>1753     fn possible_values(
1754         &self,
1755     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
1756         Some(Box::new(Self::possible_values()))
1757     }
1758 }
1759 
1760 impl Default for FalseyValueParser {
default() -> Self1761     fn default() -> Self {
1762         Self::new()
1763     }
1764 }
1765 
1766 /// Parse bool-like string values, everything else is `true`
1767 ///
1768 /// See also:
1769 /// - [`ValueParser::bool`] for different human readable bool representations
1770 /// - [`FalseyValueParser`] for assuming non-false is true
1771 ///
1772 /// # Example
1773 ///
1774 /// Usage:
1775 /// ```rust
1776 /// let mut cmd = clap::Command::new("raw")
1777 ///     .arg(
1778 ///         clap::Arg::new("append")
1779 ///             .value_parser(clap::builder::BoolishValueParser::new())
1780 ///             .required(true)
1781 ///     );
1782 ///
1783 /// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap();
1784 /// let port: bool = *m.get_one("append")
1785 ///     .expect("required");
1786 /// assert_eq!(port, true);
1787 /// ```
1788 ///
1789 /// Semantics:
1790 /// ```rust
1791 /// # use std::ffi::OsStr;
1792 /// # use clap::builder::TypedValueParser;
1793 /// # let cmd = clap::Command::new("test");
1794 /// # let arg = None;
1795 /// let value_parser = clap::builder::BoolishValueParser::new();
1796 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
1797 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1798 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("100")).is_err());
1799 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("true")).unwrap(), true);
1800 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("Yes")).unwrap(), true);
1801 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("oN")).unwrap(), true);
1802 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("1")).unwrap(), true);
1803 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("false")).unwrap(), false);
1804 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("No")).unwrap(), false);
1805 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("oFF")).unwrap(), false);
1806 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), false);
1807 /// ```
1808 #[derive(Copy, Clone, Debug)]
1809 #[non_exhaustive]
1810 pub struct BoolishValueParser {}
1811 
1812 impl BoolishValueParser {
1813     /// Parse bool-like string values, everything else is `true`
new() -> Self1814     pub fn new() -> Self {
1815         Self {}
1816     }
1817 
possible_values() -> impl Iterator<Item = crate::builder::PossibleValue>1818     fn possible_values() -> impl Iterator<Item = crate::builder::PossibleValue> {
1819         crate::util::TRUE_LITERALS
1820             .iter()
1821             .chain(crate::util::FALSE_LITERALS.iter())
1822             .copied()
1823             .map(|l| crate::builder::PossibleValue::new(l).hide(l != "true" && l != "false"))
1824     }
1825 }
1826 
1827 impl TypedValueParser for BoolishValueParser {
1828     type Value = bool;
1829 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1830     fn parse_ref(
1831         &self,
1832         cmd: &crate::Command,
1833         arg: Option<&crate::Arg>,
1834         value: &std::ffi::OsStr,
1835     ) -> Result<Self::Value, crate::Error> {
1836         let value = ok!(value.to_str().ok_or_else(|| {
1837             crate::Error::invalid_utf8(
1838                 cmd,
1839                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1840             )
1841         }));
1842         let value = ok!(crate::util::str_to_bool(value).ok_or_else(|| {
1843             let arg = arg
1844                 .map(|a| a.to_string())
1845                 .unwrap_or_else(|| "...".to_owned());
1846             crate::Error::value_validation(arg, value.to_owned(), "value was not a boolean".into())
1847                 .with_cmd(cmd)
1848         }));
1849         Ok(value)
1850     }
1851 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>1852     fn possible_values(
1853         &self,
1854     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
1855         Some(Box::new(Self::possible_values()))
1856     }
1857 }
1858 
1859 impl Default for BoolishValueParser {
default() -> Self1860     fn default() -> Self {
1861         Self::new()
1862     }
1863 }
1864 
1865 /// Parse non-empty string values
1866 ///
1867 /// See also:
1868 /// - [`ValueParser::string`]
1869 ///
1870 /// # Example
1871 ///
1872 /// Usage:
1873 /// ```rust
1874 /// let mut cmd = clap::Command::new("raw")
1875 ///     .arg(
1876 ///         clap::Arg::new("append")
1877 ///             .value_parser(clap::builder::NonEmptyStringValueParser::new())
1878 ///             .required(true)
1879 ///     );
1880 ///
1881 /// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap();
1882 /// let port: &String = m.get_one("append")
1883 ///     .expect("required");
1884 /// assert_eq!(port, "true");
1885 /// ```
1886 ///
1887 /// Semantics:
1888 /// ```rust
1889 /// # use std::ffi::OsStr;
1890 /// # use clap::builder::TypedValueParser;
1891 /// # let cmd = clap::Command::new("test");
1892 /// # let arg = None;
1893 /// let value_parser = clap::builder::NonEmptyStringValueParser::new();
1894 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).unwrap(), "random");
1895 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1896 /// ```
1897 #[derive(Copy, Clone, Debug)]
1898 #[non_exhaustive]
1899 pub struct NonEmptyStringValueParser {}
1900 
1901 impl NonEmptyStringValueParser {
1902     /// Parse non-empty string values
new() -> Self1903     pub fn new() -> Self {
1904         Self {}
1905     }
1906 }
1907 
1908 impl TypedValueParser for NonEmptyStringValueParser {
1909     type Value = String;
1910 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1911     fn parse_ref(
1912         &self,
1913         cmd: &crate::Command,
1914         arg: Option<&crate::Arg>,
1915         value: &std::ffi::OsStr,
1916     ) -> Result<Self::Value, crate::Error> {
1917         if value.is_empty() {
1918             return Err(crate::Error::empty_value(
1919                 cmd,
1920                 &[],
1921                 arg.map(ToString::to_string)
1922                     .unwrap_or_else(|| "...".to_owned()),
1923             ));
1924         }
1925         let value = ok!(value.to_str().ok_or_else(|| {
1926             crate::Error::invalid_utf8(
1927                 cmd,
1928                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1929             )
1930         }));
1931         Ok(value.to_owned())
1932     }
1933 }
1934 
1935 impl Default for NonEmptyStringValueParser {
default() -> Self1936     fn default() -> Self {
1937         Self::new()
1938     }
1939 }
1940 
1941 /// Adapt a `TypedValueParser` from one value to another
1942 ///
1943 /// See [`TypedValueParser::map`]
1944 #[derive(Clone, Debug)]
1945 pub struct MapValueParser<P, F> {
1946     parser: P,
1947     func: F,
1948 }
1949 
1950 impl<P, F, T> MapValueParser<P, F>
1951 where
1952     P: TypedValueParser,
1953     P::Value: Send + Sync + Clone,
1954     F: Fn(P::Value) -> T + Clone,
1955     T: Send + Sync + Clone,
1956 {
new(parser: P, func: F) -> Self1957     fn new(parser: P, func: F) -> Self {
1958         Self { parser, func }
1959     }
1960 }
1961 
1962 impl<P, F, T> TypedValueParser for MapValueParser<P, F>
1963 where
1964     P: TypedValueParser,
1965     P::Value: Send + Sync + Clone,
1966     F: Fn(P::Value) -> T + Clone + Send + Sync + 'static,
1967     T: Send + Sync + Clone,
1968 {
1969     type Value = T;
1970 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1971     fn parse_ref(
1972         &self,
1973         cmd: &crate::Command,
1974         arg: Option<&crate::Arg>,
1975         value: &std::ffi::OsStr,
1976     ) -> Result<Self::Value, crate::Error> {
1977         let value = ok!(self.parser.parse_ref(cmd, arg, value));
1978         let value = (self.func)(value);
1979         Ok(value)
1980     }
1981 
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<Self::Value, crate::Error>1982     fn parse(
1983         &self,
1984         cmd: &crate::Command,
1985         arg: Option<&crate::Arg>,
1986         value: std::ffi::OsString,
1987     ) -> Result<Self::Value, crate::Error> {
1988         let value = ok!(self.parser.parse(cmd, arg, value));
1989         let value = (self.func)(value);
1990         Ok(value)
1991     }
1992 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>1993     fn possible_values(
1994         &self,
1995     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
1996         self.parser.possible_values()
1997     }
1998 }
1999 
2000 /// Adapt a `TypedValueParser` from one value to another
2001 ///
2002 /// See [`TypedValueParser::try_map`]
2003 #[derive(Clone, Debug)]
2004 pub struct TryMapValueParser<P, F> {
2005     parser: P,
2006     func: F,
2007 }
2008 
2009 impl<P, F, T, E> TryMapValueParser<P, F>
2010 where
2011     P: TypedValueParser,
2012     P::Value: Send + Sync + Clone,
2013     F: Fn(P::Value) -> Result<T, E> + Clone + Send + Sync + 'static,
2014     T: Send + Sync + Clone,
2015     E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
2016 {
new(parser: P, func: F) -> Self2017     fn new(parser: P, func: F) -> Self {
2018         Self { parser, func }
2019     }
2020 }
2021 
2022 impl<P, F, T, E> TypedValueParser for TryMapValueParser<P, F>
2023 where
2024     P: TypedValueParser,
2025     P::Value: Send + Sync + Clone,
2026     F: Fn(P::Value) -> Result<T, E> + Clone + Send + Sync + 'static,
2027     T: Send + Sync + Clone,
2028     E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
2029 {
2030     type Value = T;
2031 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>2032     fn parse_ref(
2033         &self,
2034         cmd: &crate::Command,
2035         arg: Option<&crate::Arg>,
2036         value: &std::ffi::OsStr,
2037     ) -> Result<Self::Value, crate::Error> {
2038         let mid_value = ok!(self.parser.parse_ref(cmd, arg, value));
2039         let value = ok!((self.func)(mid_value).map_err(|e| {
2040             let arg = arg
2041                 .map(|a| a.to_string())
2042                 .unwrap_or_else(|| "...".to_owned());
2043             crate::Error::value_validation(arg, value.to_string_lossy().into_owned(), e.into())
2044                 .with_cmd(cmd)
2045         }));
2046         Ok(value)
2047     }
2048 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>2049     fn possible_values(
2050         &self,
2051     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> {
2052         self.parser.possible_values()
2053     }
2054 }
2055 
2056 /// Register a type with [value_parser!][crate::value_parser!]
2057 ///
2058 /// # Example
2059 ///
2060 /// ```rust
2061 /// #[derive(Copy, Clone, Debug)]
2062 /// pub struct Custom(u32);
2063 ///
2064 /// impl clap::builder::ValueParserFactory for Custom {
2065 ///     type Parser = CustomValueParser;
2066 ///     fn value_parser() -> Self::Parser {
2067 ///         CustomValueParser
2068 ///     }
2069 /// }
2070 ///
2071 /// #[derive(Clone, Debug)]
2072 /// pub struct CustomValueParser;
2073 /// impl clap::builder::TypedValueParser for CustomValueParser {
2074 ///     type Value = Custom;
2075 ///
2076 ///     fn parse_ref(
2077 ///         &self,
2078 ///         cmd: &clap::Command,
2079 ///         arg: Option<&clap::Arg>,
2080 ///         value: &std::ffi::OsStr,
2081 ///     ) -> Result<Self::Value, clap::Error> {
2082 ///         let inner = clap::value_parser!(u32);
2083 ///         let val = inner.parse_ref(cmd, arg, value)?;
2084 ///         Ok(Custom(val))
2085 ///     }
2086 /// }
2087 ///
2088 /// let parser: CustomValueParser = clap::value_parser!(Custom);
2089 /// ```
2090 pub trait ValueParserFactory {
2091     /// Generated parser, usually [`ValueParser`].
2092     ///
2093     /// It should at least be a type that supports `Into<ValueParser>`.  A non-`ValueParser` type
2094     /// allows the caller to do further initialization on the parser.
2095     type Parser;
2096 
2097     /// Create the specified [`Self::Parser`]
value_parser() -> Self::Parser2098     fn value_parser() -> Self::Parser;
2099 }
2100 impl ValueParserFactory for String {
2101     type Parser = ValueParser;
value_parser() -> Self::Parser2102     fn value_parser() -> Self::Parser {
2103         ValueParser::string() // Default `clap_derive` to optimized implementation
2104     }
2105 }
2106 impl ValueParserFactory for std::ffi::OsString {
2107     type Parser = ValueParser;
value_parser() -> Self::Parser2108     fn value_parser() -> Self::Parser {
2109         ValueParser::os_string() // Default `clap_derive` to optimized implementation
2110     }
2111 }
2112 impl ValueParserFactory for std::path::PathBuf {
2113     type Parser = ValueParser;
value_parser() -> Self::Parser2114     fn value_parser() -> Self::Parser {
2115         ValueParser::path_buf() // Default `clap_derive` to optimized implementation
2116     }
2117 }
2118 impl ValueParserFactory for bool {
2119     type Parser = ValueParser;
value_parser() -> Self::Parser2120     fn value_parser() -> Self::Parser {
2121         ValueParser::bool() // Default `clap_derive` to optimized implementation
2122     }
2123 }
2124 impl ValueParserFactory for u8 {
2125     type Parser = RangedI64ValueParser<u8>;
value_parser() -> Self::Parser2126     fn value_parser() -> Self::Parser {
2127         let start: i64 = u8::MIN.into();
2128         let end: i64 = u8::MAX.into();
2129         RangedI64ValueParser::new().range(start..=end)
2130     }
2131 }
2132 impl ValueParserFactory for i8 {
2133     type Parser = RangedI64ValueParser<i8>;
value_parser() -> Self::Parser2134     fn value_parser() -> Self::Parser {
2135         let start: i64 = i8::MIN.into();
2136         let end: i64 = i8::MAX.into();
2137         RangedI64ValueParser::new().range(start..=end)
2138     }
2139 }
2140 impl ValueParserFactory for u16 {
2141     type Parser = RangedI64ValueParser<u16>;
value_parser() -> Self::Parser2142     fn value_parser() -> Self::Parser {
2143         let start: i64 = u16::MIN.into();
2144         let end: i64 = u16::MAX.into();
2145         RangedI64ValueParser::new().range(start..=end)
2146     }
2147 }
2148 impl ValueParserFactory for i16 {
2149     type Parser = RangedI64ValueParser<i16>;
value_parser() -> Self::Parser2150     fn value_parser() -> Self::Parser {
2151         let start: i64 = i16::MIN.into();
2152         let end: i64 = i16::MAX.into();
2153         RangedI64ValueParser::new().range(start..=end)
2154     }
2155 }
2156 impl ValueParserFactory for u32 {
2157     type Parser = RangedI64ValueParser<u32>;
value_parser() -> Self::Parser2158     fn value_parser() -> Self::Parser {
2159         let start: i64 = u32::MIN.into();
2160         let end: i64 = u32::MAX.into();
2161         RangedI64ValueParser::new().range(start..=end)
2162     }
2163 }
2164 impl ValueParserFactory for i32 {
2165     type Parser = RangedI64ValueParser<i32>;
value_parser() -> Self::Parser2166     fn value_parser() -> Self::Parser {
2167         let start: i64 = i32::MIN.into();
2168         let end: i64 = i32::MAX.into();
2169         RangedI64ValueParser::new().range(start..=end)
2170     }
2171 }
2172 impl ValueParserFactory for i64 {
2173     type Parser = RangedI64ValueParser<i64>;
value_parser() -> Self::Parser2174     fn value_parser() -> Self::Parser {
2175         RangedI64ValueParser::new()
2176     }
2177 }
2178 impl ValueParserFactory for u64 {
2179     type Parser = RangedU64ValueParser<u64>;
value_parser() -> Self::Parser2180     fn value_parser() -> Self::Parser {
2181         RangedU64ValueParser::new()
2182     }
2183 }
2184 
2185 #[doc(hidden)]
2186 #[derive(Debug)]
2187 pub struct _AutoValueParser<T>(std::marker::PhantomData<T>);
2188 
2189 impl<T> _AutoValueParser<T> {
2190     #[doc(hidden)]
2191     #[allow(clippy::new_without_default)]
new() -> Self2192     pub fn new() -> Self {
2193         Self(Default::default())
2194     }
2195 }
2196 
2197 /// Unstable [`ValueParser`]
2198 ///
2199 /// Implementation may change to more specific instance in the future
2200 #[doc(hidden)]
2201 #[derive(Debug)]
2202 pub struct _AnonymousValueParser(ValueParser);
2203 
2204 #[doc(hidden)]
2205 pub mod via_prelude {
2206     use super::*;
2207 
2208     #[doc(hidden)]
2209     pub trait _ValueParserViaFactory: private::_ValueParserViaFactorySealed {
2210         type Parser;
value_parser(&self) -> Self::Parser2211         fn value_parser(&self) -> Self::Parser;
2212     }
2213     impl<P: ValueParserFactory> _ValueParserViaFactory for &&&&&&_AutoValueParser<P> {
2214         type Parser = P::Parser;
value_parser(&self) -> Self::Parser2215         fn value_parser(&self) -> Self::Parser {
2216             P::value_parser()
2217         }
2218     }
2219 
2220     #[doc(hidden)]
2221     pub trait _ValueParserViaValueEnum: private::_ValueParserViaValueEnumSealed {
2222         type Output;
2223 
value_parser(&self) -> Self::Output2224         fn value_parser(&self) -> Self::Output;
2225     }
2226     impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> _ValueParserViaValueEnum
2227         for &&&&&_AutoValueParser<E>
2228     {
2229         type Output = EnumValueParser<E>;
2230 
value_parser(&self) -> Self::Output2231         fn value_parser(&self) -> Self::Output {
2232             EnumValueParser::<E>::new()
2233         }
2234     }
2235 
2236     #[doc(hidden)]
2237     pub trait _ValueParserViaFromOsString: private::_ValueParserViaFromOsStringSealed {
value_parser(&self) -> _AnonymousValueParser2238         fn value_parser(&self) -> _AnonymousValueParser;
2239     }
2240     impl<FromOsString> _ValueParserViaFromOsString for &&&&_AutoValueParser<FromOsString>
2241     where
2242         FromOsString: From<std::ffi::OsString> + std::any::Any + Clone + Send + Sync + 'static,
2243     {
value_parser(&self) -> _AnonymousValueParser2244         fn value_parser(&self) -> _AnonymousValueParser {
2245             _AnonymousValueParser(
2246                 OsStringValueParser::new()
2247                     .map(|s| FromOsString::from(s))
2248                     .into(),
2249             )
2250         }
2251     }
2252 
2253     #[doc(hidden)]
2254     pub trait _ValueParserViaFromOsStr: private::_ValueParserViaFromOsStrSealed {
value_parser(&self) -> _AnonymousValueParser2255         fn value_parser(&self) -> _AnonymousValueParser;
2256     }
2257     impl<FromOsStr> _ValueParserViaFromOsStr for &&&_AutoValueParser<FromOsStr>
2258     where
2259         FromOsStr:
2260             for<'s> From<&'s std::ffi::OsStr> + std::any::Any + Clone + Send + Sync + 'static,
2261     {
value_parser(&self) -> _AnonymousValueParser2262         fn value_parser(&self) -> _AnonymousValueParser {
2263             _AnonymousValueParser(
2264                 OsStringValueParser::new()
2265                     .map(|s| FromOsStr::from(&s))
2266                     .into(),
2267             )
2268         }
2269     }
2270 
2271     #[doc(hidden)]
2272     pub trait _ValueParserViaFromString: private::_ValueParserViaFromStringSealed {
value_parser(&self) -> _AnonymousValueParser2273         fn value_parser(&self) -> _AnonymousValueParser;
2274     }
2275     impl<FromString> _ValueParserViaFromString for &&_AutoValueParser<FromString>
2276     where
2277         FromString: From<String> + std::any::Any + Clone + Send + Sync + 'static,
2278     {
value_parser(&self) -> _AnonymousValueParser2279         fn value_parser(&self) -> _AnonymousValueParser {
2280             _AnonymousValueParser(StringValueParser::new().map(|s| FromString::from(s)).into())
2281         }
2282     }
2283 
2284     #[doc(hidden)]
2285     pub trait _ValueParserViaFromStr: private::_ValueParserViaFromStrSealed {
value_parser(&self) -> _AnonymousValueParser2286         fn value_parser(&self) -> _AnonymousValueParser;
2287     }
2288     impl<FromStr> _ValueParserViaFromStr for &_AutoValueParser<FromStr>
2289     where
2290         FromStr: for<'s> From<&'s str> + std::any::Any + Clone + Send + Sync + 'static,
2291     {
value_parser(&self) -> _AnonymousValueParser2292         fn value_parser(&self) -> _AnonymousValueParser {
2293             _AnonymousValueParser(StringValueParser::new().map(|s| FromStr::from(&s)).into())
2294         }
2295     }
2296 
2297     #[doc(hidden)]
2298     pub trait _ValueParserViaParse: private::_ValueParserViaParseSealed {
value_parser(&self) -> _AnonymousValueParser2299         fn value_parser(&self) -> _AnonymousValueParser;
2300     }
2301     impl<Parse> _ValueParserViaParse for _AutoValueParser<Parse>
2302     where
2303         Parse: std::str::FromStr + std::any::Any + Clone + Send + Sync + 'static,
2304         <Parse as std::str::FromStr>::Err: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
2305     {
value_parser(&self) -> _AnonymousValueParser2306         fn value_parser(&self) -> _AnonymousValueParser {
2307             let func: fn(&str) -> Result<Parse, <Parse as std::str::FromStr>::Err> =
2308                 Parse::from_str;
2309             _AnonymousValueParser(ValueParser::new(func))
2310         }
2311     }
2312 }
2313 
2314 /// Select a [`ValueParser`] implementation from the intended type
2315 ///
2316 /// Supported types
2317 /// - [`ValueParserFactory` types][ValueParserFactory], including
2318 ///   - [Native types][ValueParser]: `bool`, `String`, `OsString`, `PathBuf`
2319 ///   - [Ranged numeric types][RangedI64ValueParser]: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`
2320 /// - [`ValueEnum` types][crate::ValueEnum]
2321 /// - [`From<OsString>` types][std::convert::From] and [`From<&OsStr>` types][std::convert::From]
2322 /// - [`From<String>` types][std::convert::From] and [`From<&str>` types][std::convert::From]
2323 /// - [`FromStr` types][std::str::FromStr], including usize, isize
2324 ///
2325 /// # Example
2326 ///
2327 /// Usage:
2328 /// ```rust
2329 /// # use std::path::PathBuf;
2330 /// # use std::path::Path;
2331 /// let mut cmd = clap::Command::new("raw")
2332 ///     .arg(
2333 ///         clap::Arg::new("output")
2334 ///             .value_parser(clap::value_parser!(PathBuf))
2335 ///             .required(true)
2336 ///     );
2337 ///
2338 /// let m = cmd.try_get_matches_from_mut(["cmd", "file.txt"]).unwrap();
2339 /// let port: &PathBuf = m.get_one("output")
2340 ///     .expect("required");
2341 /// assert_eq!(port, Path::new("file.txt"));
2342 /// ```
2343 ///
2344 /// Example mappings:
2345 /// ```rust
2346 /// # use clap::ColorChoice;
2347 /// // Built-in types
2348 /// let parser = clap::value_parser!(String);
2349 /// assert_eq!(format!("{:?}", parser), "ValueParser::string");
2350 /// let parser = clap::value_parser!(std::ffi::OsString);
2351 /// assert_eq!(format!("{:?}", parser), "ValueParser::os_string");
2352 /// let parser = clap::value_parser!(std::path::PathBuf);
2353 /// assert_eq!(format!("{:?}", parser), "ValueParser::path_buf");
2354 /// clap::value_parser!(u16).range(3000..);
2355 /// clap::value_parser!(u64).range(3000..);
2356 ///
2357 /// // FromStr types
2358 /// let parser = clap::value_parser!(usize);
2359 /// assert_eq!(format!("{:?}", parser), "_AnonymousValueParser(ValueParser::other(usize))");
2360 ///
2361 /// // ValueEnum types
2362 /// clap::value_parser!(ColorChoice);
2363 /// ```
2364 #[macro_export]
2365 macro_rules! value_parser {
2366     ($name:ty) => {{
2367         use $crate::builder::via_prelude::*;
2368         let auto = $crate::builder::_AutoValueParser::<$name>::new();
2369         (&&&&&&auto).value_parser()
2370     }};
2371 }
2372 
2373 mod private {
2374     use super::*;
2375 
2376     // Prefer these so `clap_derive` defaults to optimized implementations
2377     pub trait _ValueParserViaSelfSealed {}
2378     impl<P: Into<ValueParser>> _ValueParserViaSelfSealed for &&&&&&&_AutoValueParser<P> {}
2379 
2380     pub trait _ValueParserViaFactorySealed {}
2381     impl<P: ValueParserFactory> _ValueParserViaFactorySealed for &&&&&&_AutoValueParser<P> {}
2382 
2383     pub trait _ValueParserViaValueEnumSealed {}
2384     impl<E: crate::ValueEnum> _ValueParserViaValueEnumSealed for &&&&&_AutoValueParser<E> {}
2385 
2386     pub trait _ValueParserViaFromOsStringSealed {}
2387     impl<FromOsString> _ValueParserViaFromOsStringSealed for &&&&_AutoValueParser<FromOsString> where
2388         FromOsString: From<std::ffi::OsString> + std::any::Any + Send + Sync + 'static
2389     {
2390     }
2391 
2392     pub trait _ValueParserViaFromOsStrSealed {}
2393     impl<FromOsStr> _ValueParserViaFromOsStrSealed for &&&_AutoValueParser<FromOsStr> where
2394         FromOsStr: for<'s> From<&'s std::ffi::OsStr> + std::any::Any + Send + Sync + 'static
2395     {
2396     }
2397 
2398     pub trait _ValueParserViaFromStringSealed {}
2399     impl<FromString> _ValueParserViaFromStringSealed for &&_AutoValueParser<FromString> where
2400         FromString: From<String> + std::any::Any + Send + Sync + 'static
2401     {
2402     }
2403 
2404     pub trait _ValueParserViaFromStrSealed {}
2405     impl<FromStr> _ValueParserViaFromStrSealed for &_AutoValueParser<FromStr> where
2406         FromStr: for<'s> From<&'s str> + std::any::Any + Send + Sync + 'static
2407     {
2408     }
2409 
2410     pub trait _ValueParserViaParseSealed {}
2411     impl<Parse> _ValueParserViaParseSealed for _AutoValueParser<Parse>
2412     where
2413         Parse: std::str::FromStr + std::any::Any + Send + Sync + 'static,
2414         <Parse as std::str::FromStr>::Err: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
2415     {
2416     }
2417 }
2418 
2419 #[cfg(test)]
2420 mod test {
2421     use super::*;
2422 
2423     #[test]
ensure_typed_applies_to_parse()2424     fn ensure_typed_applies_to_parse() {
2425         fn parse(_: &str) -> Result<usize, std::io::Error> {
2426             Ok(10)
2427         }
2428         let cmd = crate::Command::new("cmd");
2429         let arg = None;
2430         assert_eq!(
2431             TypedValueParser::parse_ref(&parse, &cmd, arg, std::ffi::OsStr::new("foo")).unwrap(),
2432             10
2433         );
2434     }
2435 }
2436