• 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 ///             .takes_value(true)
33 ///             .required(true)
34 ///     )
35 ///     .arg(
36 ///         clap::Arg::new("port")
37 ///             .long("port")
38 ///             .value_parser(clap::value_parser!(u16).range(3000..))
39 ///             .takes_value(true)
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     /// To create a custom parser, see [`TypedValueParser`]
77     ///
78     /// Pre-existing implementations include:
79     /// - [`EnumValueParser`] and  [`PossibleValuesParser`] for static enumerated values
80     /// - [`BoolishValueParser`] and [`FalseyValueParser`] for alternative `bool` implementations
81     /// - [`RangedI64ValueParser`] and [`RangedU64ValueParser`]
82     /// - [`NonEmptyStringValueParser`]
83     ///
84     /// # Example
85     ///
86     /// ```rust
87     /// type EnvVar = (String, Option<String>);
88     /// fn parse_env_var(env: &str) -> Result<EnvVar, std::io::Error> {
89     ///     if let Some((var, value)) = env.split_once('=') {
90     ///         Ok((var.to_owned(), Some(value.to_owned())))
91     ///     } else {
92     ///         Ok((env.to_owned(), None))
93     ///     }
94     /// }
95     ///
96     /// let mut cmd = clap::Command::new("raw")
97     ///     .arg(
98     ///         clap::Arg::new("env")
99     ///             .value_parser(clap::builder::ValueParser::new(parse_env_var))
100     ///             .required(true)
101     ///     );
102     ///
103     /// let m = cmd.try_get_matches_from_mut(["cmd", "key=value"]).unwrap();
104     /// let port: &EnvVar = m.get_one("env")
105     ///     .expect("required");
106     /// assert_eq!(*port, ("key".into(), Some("value".into())));
107     /// ```
new<P>(other: P) -> Self where P: TypedValueParser, P::Value: Send + Sync + Clone,108     pub fn new<P>(other: P) -> Self
109     where
110         P: TypedValueParser,
111         P::Value: Send + Sync + Clone,
112     {
113         Self(ValueParserInner::Other(Box::new(other)))
114     }
115 
116     /// [`bool`] parser for argument values
117     ///
118     /// See also:
119     /// - [`BoolishValueParser`] for different human readable bool representations
120     /// - [`FalseyValueParser`] for assuming non-false is true
121     ///
122     /// # Example
123     ///
124     /// ```rust
125     /// let mut cmd = clap::Command::new("raw")
126     ///     .arg(
127     ///         clap::Arg::new("download")
128     ///             .value_parser(clap::value_parser!(bool))
129     ///             .required(true)
130     ///     );
131     ///
132     /// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap();
133     /// let port: bool = *m.get_one("download")
134     ///     .expect("required");
135     /// assert_eq!(port, true);
136     ///
137     /// assert!(cmd.try_get_matches_from_mut(["cmd", "forever"]).is_err());
138     /// ```
bool() -> Self139     pub const fn bool() -> Self {
140         Self(ValueParserInner::Bool)
141     }
142 
143     /// [`String`] parser for argument values
144     ///
145     /// See also:
146     /// - [`NonEmptyStringValueParser`]
147     ///
148     /// # Example
149     ///
150     /// ```rust
151     /// let mut cmd = clap::Command::new("raw")
152     ///     .arg(
153     ///         clap::Arg::new("port")
154     ///             .value_parser(clap::value_parser!(String))
155     ///             .required(true)
156     ///     );
157     ///
158     /// let m = cmd.try_get_matches_from_mut(["cmd", "80"]).unwrap();
159     /// let port: &String = m.get_one("port")
160     ///     .expect("required");
161     /// assert_eq!(port, "80");
162     /// ```
string() -> Self163     pub const fn string() -> Self {
164         Self(ValueParserInner::String)
165     }
166 
167     /// [`OsString`][std::ffi::OsString] parser for argument values
168     ///
169     /// # Example
170     ///
171     #[cfg_attr(not(unix), doc = " ```ignore")]
172     #[cfg_attr(unix, doc = " ```rust")]
173     /// # use clap::{Command, Arg, builder::ValueParser};
174     /// use std::ffi::OsString;
175     /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
176     /// let r = Command::new("myprog")
177     ///     .arg(
178     ///         Arg::new("arg")
179     ///         .required(true)
180     ///         .value_parser(ValueParser::os_string())
181     ///     )
182     ///     .try_get_matches_from(vec![
183     ///         OsString::from("myprog"),
184     ///         OsString::from_vec(vec![0xe9])
185     ///     ]);
186     ///
187     /// assert!(r.is_ok());
188     /// let m = r.unwrap();
189     /// let arg: &OsString = m.get_one("arg")
190     ///     .expect("required");
191     /// assert_eq!(arg.as_bytes(), &[0xe9]);
192     /// ```
os_string() -> Self193     pub const fn os_string() -> Self {
194         Self(ValueParserInner::OsString)
195     }
196 
197     /// [`PathBuf`][std::path::PathBuf] parser for argument values
198     ///
199     /// # Example
200     ///
201     /// ```rust
202     /// # use std::path::PathBuf;
203     /// # use std::path::Path;
204     /// let mut cmd = clap::Command::new("raw")
205     ///     .arg(
206     ///         clap::Arg::new("output")
207     ///             .value_parser(clap::value_parser!(PathBuf))
208     ///             .required(true)
209     ///     );
210     ///
211     /// let m = cmd.try_get_matches_from_mut(["cmd", "hello.txt"]).unwrap();
212     /// let port: &PathBuf = m.get_one("output")
213     ///     .expect("required");
214     /// assert_eq!(port, Path::new("hello.txt"));
215     ///
216     /// assert!(cmd.try_get_matches_from_mut(["cmd", ""]).is_err());
217     /// ```
path_buf() -> Self218     pub const fn path_buf() -> Self {
219         Self(ValueParserInner::PathBuf)
220     }
221 }
222 
223 impl ValueParser {
224     /// Parse into a `AnyValue`
225     ///
226     /// 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>227     pub(crate) fn parse_ref(
228         &self,
229         cmd: &crate::Command,
230         arg: Option<&crate::Arg>,
231         value: &std::ffi::OsStr,
232     ) -> Result<AnyValue, crate::Error> {
233         self.any_value_parser().parse_ref(cmd, arg, value)
234     }
235 
236     /// Describes the content of `AnyValue`
type_id(&self) -> AnyValueId237     pub fn type_id(&self) -> AnyValueId {
238         self.any_value_parser().type_id()
239     }
240 
241     /// Reflect on enumerated value properties
242     ///
243     /// Error checking should not be done with this; it is mostly targeted at user-facing
244     /// applications like errors and completion.
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>245     pub fn possible_values(
246         &self,
247     ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>> {
248         self.any_value_parser().possible_values()
249     }
250 
any_value_parser(&self) -> &dyn AnyValueParser251     fn any_value_parser(&self) -> &dyn AnyValueParser {
252         match &self.0 {
253             ValueParserInner::Bool => &BoolValueParser {},
254             ValueParserInner::String => &StringValueParser {},
255             ValueParserInner::OsString => &OsStringValueParser {},
256             ValueParserInner::PathBuf => &PathBufValueParser {},
257             ValueParserInner::Other(o) => o.as_ref(),
258         }
259     }
260 }
261 
262 /// Convert a [`TypedValueParser`] to [`ValueParser`]
263 ///
264 /// # Example
265 ///
266 /// ```rust
267 /// let mut cmd = clap::Command::new("raw")
268 ///     .arg(
269 ///         clap::Arg::new("hostname")
270 ///             .long("hostname")
271 ///             .value_parser(clap::builder::NonEmptyStringValueParser::new())
272 ///             .takes_value(true)
273 ///             .required(true)
274 ///     );
275 ///
276 /// let m = cmd.try_get_matches_from_mut(
277 ///     ["cmd", "--hostname", "rust-lang.org"]
278 /// ).unwrap();
279 ///
280 /// let hostname: &String = m.get_one("hostname")
281 ///     .expect("required");
282 /// assert_eq!(hostname, "rust-lang.org");
283 /// ```
284 impl<P> From<P> for ValueParser
285 where
286     P: TypedValueParser + Send + Sync + 'static,
287     P::Value: Send + Sync + Clone,
288 {
from(p: P) -> Self289     fn from(p: P) -> Self {
290         Self::new(p)
291     }
292 }
293 
294 impl From<_AnonymousValueParser> for ValueParser {
from(p: _AnonymousValueParser) -> Self295     fn from(p: _AnonymousValueParser) -> Self {
296         p.0
297     }
298 }
299 
300 /// Create an `i64` [`ValueParser`] from a `N..M` range
301 ///
302 /// See [`RangedI64ValueParser`] for more control over the output type.
303 ///
304 /// See also [`RangedU64ValueParser`]
305 ///
306 /// # Examples
307 ///
308 /// ```rust
309 /// let mut cmd = clap::Command::new("raw")
310 ///     .arg(
311 ///         clap::Arg::new("port")
312 ///             .long("port")
313 ///             .value_parser(3000..4000)
314 ///             .takes_value(true)
315 ///             .required(true)
316 ///     );
317 ///
318 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
319 /// let port: i64 = *m.get_one("port")
320 ///     .expect("required");
321 /// assert_eq!(port, 3001);
322 /// ```
323 impl From<std::ops::Range<i64>> for ValueParser {
from(value: std::ops::Range<i64>) -> Self324     fn from(value: std::ops::Range<i64>) -> Self {
325         let inner = RangedI64ValueParser::<i64>::new().range(value.start..value.end);
326         Self::from(inner)
327     }
328 }
329 
330 /// Create an `i64` [`ValueParser`] from a `N..=M` range
331 ///
332 /// See [`RangedI64ValueParser`] for more control over the output type.
333 ///
334 /// See also [`RangedU64ValueParser`]
335 ///
336 /// # Examples
337 ///
338 /// ```rust
339 /// let mut cmd = clap::Command::new("raw")
340 ///     .arg(
341 ///         clap::Arg::new("port")
342 ///             .long("port")
343 ///             .value_parser(3000..=4000)
344 ///             .takes_value(true)
345 ///             .required(true)
346 ///     );
347 ///
348 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
349 /// let port: i64 = *m.get_one("port")
350 ///     .expect("required");
351 /// assert_eq!(port, 3001);
352 /// ```
353 impl From<std::ops::RangeInclusive<i64>> for ValueParser {
from(value: std::ops::RangeInclusive<i64>) -> Self354     fn from(value: std::ops::RangeInclusive<i64>) -> Self {
355         let inner = RangedI64ValueParser::<i64>::new().range(value.start()..=value.end());
356         Self::from(inner)
357     }
358 }
359 
360 /// Create an `i64` [`ValueParser`] from a `N..` range
361 ///
362 /// See [`RangedI64ValueParser`] for more control over the output type.
363 ///
364 /// See also [`RangedU64ValueParser`]
365 ///
366 /// # Examples
367 ///
368 /// ```rust
369 /// let mut cmd = clap::Command::new("raw")
370 ///     .arg(
371 ///         clap::Arg::new("port")
372 ///             .long("port")
373 ///             .value_parser(3000..)
374 ///             .takes_value(true)
375 ///             .required(true)
376 ///     );
377 ///
378 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
379 /// let port: i64 = *m.get_one("port")
380 ///     .expect("required");
381 /// assert_eq!(port, 3001);
382 /// ```
383 impl From<std::ops::RangeFrom<i64>> for ValueParser {
from(value: std::ops::RangeFrom<i64>) -> Self384     fn from(value: std::ops::RangeFrom<i64>) -> Self {
385         let inner = RangedI64ValueParser::<i64>::new().range(value.start..);
386         Self::from(inner)
387     }
388 }
389 
390 /// Create an `i64` [`ValueParser`] from a `..M` range
391 ///
392 /// See [`RangedI64ValueParser`] for more control over the output type.
393 ///
394 /// See also [`RangedU64ValueParser`]
395 ///
396 /// # Examples
397 ///
398 /// ```rust
399 /// let mut cmd = clap::Command::new("raw")
400 ///     .arg(
401 ///         clap::Arg::new("port")
402 ///             .long("port")
403 ///             .value_parser(..3000)
404 ///             .takes_value(true)
405 ///             .required(true)
406 ///     );
407 ///
408 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "80"]).unwrap();
409 /// let port: i64 = *m.get_one("port")
410 ///     .expect("required");
411 /// assert_eq!(port, 80);
412 /// ```
413 impl From<std::ops::RangeTo<i64>> for ValueParser {
from(value: std::ops::RangeTo<i64>) -> Self414     fn from(value: std::ops::RangeTo<i64>) -> Self {
415         let inner = RangedI64ValueParser::<i64>::new().range(..value.end);
416         Self::from(inner)
417     }
418 }
419 
420 /// Create an `i64` [`ValueParser`] from a `..=M` range
421 ///
422 /// See [`RangedI64ValueParser`] for more control over the output type.
423 ///
424 /// See also [`RangedU64ValueParser`]
425 ///
426 /// # Examples
427 ///
428 /// ```rust
429 /// let mut cmd = clap::Command::new("raw")
430 ///     .arg(
431 ///         clap::Arg::new("port")
432 ///             .long("port")
433 ///             .value_parser(..=3000)
434 ///             .takes_value(true)
435 ///             .required(true)
436 ///     );
437 ///
438 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "80"]).unwrap();
439 /// let port: i64 = *m.get_one("port")
440 ///     .expect("required");
441 /// assert_eq!(port, 80);
442 /// ```
443 impl From<std::ops::RangeToInclusive<i64>> for ValueParser {
from(value: std::ops::RangeToInclusive<i64>) -> Self444     fn from(value: std::ops::RangeToInclusive<i64>) -> Self {
445         let inner = RangedI64ValueParser::<i64>::new().range(..=value.end);
446         Self::from(inner)
447     }
448 }
449 
450 /// Create an `i64` [`ValueParser`] from a `..` range
451 ///
452 /// See [`RangedI64ValueParser`] for more control over the output type.
453 ///
454 /// See also [`RangedU64ValueParser`]
455 ///
456 /// # Examples
457 ///
458 /// ```rust
459 /// let mut cmd = clap::Command::new("raw")
460 ///     .arg(
461 ///         clap::Arg::new("port")
462 ///             .long("port")
463 ///             .value_parser(..)
464 ///             .takes_value(true)
465 ///             .required(true)
466 ///     );
467 ///
468 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
469 /// let port: i64 = *m.get_one("port")
470 ///     .expect("required");
471 /// assert_eq!(port, 3001);
472 /// ```
473 impl From<std::ops::RangeFull> for ValueParser {
from(value: std::ops::RangeFull) -> Self474     fn from(value: std::ops::RangeFull) -> Self {
475         let inner = RangedI64ValueParser::<i64>::new().range(value);
476         Self::from(inner)
477     }
478 }
479 
480 /// Create a [`ValueParser`] with [`PossibleValuesParser`]
481 ///
482 /// See [`PossibleValuesParser`] for more flexibility in creating the
483 /// [`PossibleValue`][crate::PossibleValue]s.
484 ///
485 /// # Examples
486 ///
487 /// ```rust
488 /// let mut cmd = clap::Command::new("raw")
489 ///     .arg(
490 ///         clap::Arg::new("color")
491 ///             .long("color")
492 ///             .value_parser(["always", "auto", "never"])
493 ///             .default_value("auto")
494 ///     );
495 ///
496 /// let m = cmd.try_get_matches_from_mut(
497 ///     ["cmd", "--color", "never"]
498 /// ).unwrap();
499 ///
500 /// let color: &String = m.get_one("color")
501 ///     .expect("default");
502 /// assert_eq!(color, "never");
503 /// ```
504 impl<P, const C: usize> From<[P; C]> for ValueParser
505 where
506     P: Into<super::PossibleValue<'static>>,
507 {
from(values: [P; C]) -> Self508     fn from(values: [P; C]) -> Self {
509         let inner = PossibleValuesParser::from(values);
510         Self::from(inner)
511     }
512 }
513 
514 impl std::fmt::Debug for ValueParser {
fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error>515     fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
516         match &self.0 {
517             ValueParserInner::Bool => f.debug_struct("ValueParser::bool").finish(),
518             ValueParserInner::String => f.debug_struct("ValueParser::string").finish(),
519             ValueParserInner::OsString => f.debug_struct("ValueParser::os_string").finish(),
520             ValueParserInner::PathBuf => f.debug_struct("ValueParser::path_buf").finish(),
521             ValueParserInner::Other(o) => write!(f, "ValueParser::other({:?})", o.type_id()),
522         }
523     }
524 }
525 
526 impl Clone for ValueParser {
clone(&self) -> Self527     fn clone(&self) -> Self {
528         Self(match &self.0 {
529             ValueParserInner::Bool => ValueParserInner::Bool,
530             ValueParserInner::String => ValueParserInner::String,
531             ValueParserInner::OsString => ValueParserInner::OsString,
532             ValueParserInner::PathBuf => ValueParserInner::PathBuf,
533             ValueParserInner::Other(o) => ValueParserInner::Other(o.clone_any()),
534         })
535     }
536 }
537 
538 /// A type-erased wrapper for [`TypedValueParser`].
539 trait AnyValueParser: Send + Sync + 'static {
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<AnyValue, crate::Error>540     fn parse_ref(
541         &self,
542         cmd: &crate::Command,
543         arg: Option<&crate::Arg>,
544         value: &std::ffi::OsStr,
545     ) -> Result<AnyValue, crate::Error>;
546 
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<AnyValue, crate::Error>547     fn parse(
548         &self,
549         cmd: &crate::Command,
550         arg: Option<&crate::Arg>,
551         value: std::ffi::OsString,
552     ) -> Result<AnyValue, crate::Error>;
553 
554     /// Describes the content of `AnyValue`
type_id(&self) -> AnyValueId555     fn type_id(&self) -> AnyValueId;
556 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>557     fn possible_values(
558         &self,
559     ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>;
560 
clone_any(&self) -> Box<dyn AnyValueParser>561     fn clone_any(&self) -> Box<dyn AnyValueParser>;
562 }
563 
564 impl<T, P> AnyValueParser for P
565 where
566     T: std::any::Any + Clone + Send + Sync + 'static,
567     P: TypedValueParser<Value = T>,
568 {
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<AnyValue, crate::Error>569     fn parse_ref(
570         &self,
571         cmd: &crate::Command,
572         arg: Option<&crate::Arg>,
573         value: &std::ffi::OsStr,
574     ) -> Result<AnyValue, crate::Error> {
575         let value = TypedValueParser::parse_ref(self, cmd, arg, value)?;
576         Ok(AnyValue::new(value))
577     }
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         let value = TypedValueParser::parse(self, cmd, arg, value)?;
586         Ok(AnyValue::new(value))
587     }
588 
type_id(&self) -> AnyValueId589     fn type_id(&self) -> AnyValueId {
590         AnyValueId::of::<T>()
591     }
592 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>593     fn possible_values(
594         &self,
595     ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>> {
596         P::possible_values(self)
597     }
598 
clone_any(&self) -> Box<dyn AnyValueParser>599     fn clone_any(&self) -> Box<dyn AnyValueParser> {
600         Box::new(self.clone())
601     }
602 }
603 
604 /// Parse/validate argument values
605 pub trait TypedValueParser: Clone + Send + Sync + 'static {
606     /// Argument's value type
607     type Value;
608 
609     /// Parse the argument value
610     ///
611     /// 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>612     fn parse_ref(
613         &self,
614         cmd: &crate::Command,
615         arg: Option<&crate::Arg>,
616         value: &std::ffi::OsStr,
617     ) -> Result<Self::Value, crate::Error>;
618 
619     /// Parse the argument value
620     ///
621     /// 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>622     fn parse(
623         &self,
624         cmd: &crate::Command,
625         arg: Option<&crate::Arg>,
626         value: std::ffi::OsString,
627     ) -> Result<Self::Value, crate::Error> {
628         self.parse_ref(cmd, arg, &value)
629     }
630 
631     /// Reflect on enumerated value properties
632     ///
633     /// Error checking should not be done with this; it is mostly targeted at user-facing
634     /// applications like errors and completion.
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>635     fn possible_values(
636         &self,
637     ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>> {
638         None
639     }
640 
641     /// Adapt a `TypedValueParser` from one value to another
642     ///
643     /// # Example
644     ///
645     /// ```rust
646     /// # use clap::Command;
647     /// # use clap::Arg;
648     /// # use clap::builder::TypedValueParser as _;
649     /// # use clap::builder::BoolishValueParser;
650     /// let cmd = Command::new("mycmd")
651     ///     .arg(
652     ///         Arg::new("flag")
653     ///             .long("flag")
654     ///             .action(clap::ArgAction::Set)
655     ///             .value_parser(
656     ///                 BoolishValueParser::new()
657     ///                 .map(|b| -> usize {
658     ///                     if b { 10 } else { 5 }
659     ///                 })
660     ///             )
661     ///     );
662     ///
663     /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag=true", "--flag=true"]).unwrap();
664     /// assert!(matches.contains_id("flag"));
665     /// assert_eq!(
666     ///     matches.get_one::<usize>("flag").copied(),
667     ///     Some(10)
668     /// );
669     ///
670     /// let matches = cmd.try_get_matches_from(["mycmd", "--flag=false"]).unwrap();
671     /// assert!(matches.contains_id("flag"));
672     /// assert_eq!(
673     ///     matches.get_one::<usize>("flag").copied(),
674     ///     Some(5)
675     /// );
676     /// ```
map<T, F>(self, func: F) -> MapValueParser<Self, F> where T: Send + Sync + Clone, F: Fn(Self::Value) -> T + Clone,677     fn map<T, F>(self, func: F) -> MapValueParser<Self, F>
678     where
679         T: Send + Sync + Clone,
680         F: Fn(Self::Value) -> T + Clone,
681     {
682         MapValueParser::new(self, func)
683     }
684 }
685 
686 impl<F, T, E> TypedValueParser for F
687 where
688     F: Fn(&str) -> Result<T, E> + Clone + Send + Sync + 'static,
689     E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
690 {
691     type Value = T;
692 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>693     fn parse_ref(
694         &self,
695         cmd: &crate::Command,
696         arg: Option<&crate::Arg>,
697         value: &std::ffi::OsStr,
698     ) -> Result<Self::Value, crate::Error> {
699         let value = value.to_str().ok_or_else(|| {
700             crate::Error::invalid_utf8(
701                 cmd,
702                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
703             )
704         })?;
705         let value = (self)(value).map_err(|e| {
706             let arg = arg
707                 .map(|a| a.to_string())
708                 .unwrap_or_else(|| "...".to_owned());
709             crate::Error::value_validation(arg, value.to_owned(), e.into()).with_cmd(cmd)
710         })?;
711         Ok(value)
712     }
713 }
714 
715 /// Implementation for [`ValueParser::string`]
716 ///
717 /// Useful for composing new [`TypedValueParser`]s
718 #[derive(Copy, Clone, Debug)]
719 #[non_exhaustive]
720 pub struct StringValueParser {}
721 
722 impl StringValueParser {
723     /// Implementation for [`ValueParser::string`]
new() -> Self724     pub fn new() -> Self {
725         Self {}
726     }
727 }
728 
729 impl TypedValueParser for StringValueParser {
730     type Value = String;
731 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>732     fn parse_ref(
733         &self,
734         cmd: &crate::Command,
735         arg: Option<&crate::Arg>,
736         value: &std::ffi::OsStr,
737     ) -> Result<Self::Value, crate::Error> {
738         TypedValueParser::parse(self, cmd, arg, value.to_owned())
739     }
740 
parse( &self, cmd: &crate::Command, _arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<Self::Value, crate::Error>741     fn parse(
742         &self,
743         cmd: &crate::Command,
744         _arg: Option<&crate::Arg>,
745         value: std::ffi::OsString,
746     ) -> Result<Self::Value, crate::Error> {
747         let value = value.into_string().map_err(|_| {
748             crate::Error::invalid_utf8(
749                 cmd,
750                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
751             )
752         })?;
753         Ok(value)
754     }
755 }
756 
757 impl Default for StringValueParser {
default() -> Self758     fn default() -> Self {
759         Self::new()
760     }
761 }
762 
763 /// Implementation for [`ValueParser::os_string`]
764 ///
765 /// Useful for composing new [`TypedValueParser`]s
766 #[derive(Copy, Clone, Debug)]
767 #[non_exhaustive]
768 pub struct OsStringValueParser {}
769 
770 impl OsStringValueParser {
771     /// Implementation for [`ValueParser::os_string`]
new() -> Self772     pub fn new() -> Self {
773         Self {}
774     }
775 }
776 
777 impl TypedValueParser for OsStringValueParser {
778     type Value = std::ffi::OsString;
779 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>780     fn parse_ref(
781         &self,
782         cmd: &crate::Command,
783         arg: Option<&crate::Arg>,
784         value: &std::ffi::OsStr,
785     ) -> Result<Self::Value, crate::Error> {
786         TypedValueParser::parse(self, cmd, arg, value.to_owned())
787     }
788 
parse( &self, _cmd: &crate::Command, _arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<Self::Value, crate::Error>789     fn parse(
790         &self,
791         _cmd: &crate::Command,
792         _arg: Option<&crate::Arg>,
793         value: std::ffi::OsString,
794     ) -> Result<Self::Value, crate::Error> {
795         Ok(value)
796     }
797 }
798 
799 impl Default for OsStringValueParser {
default() -> Self800     fn default() -> Self {
801         Self::new()
802     }
803 }
804 
805 /// Implementation for [`ValueParser::path_buf`]
806 ///
807 /// Useful for composing new [`TypedValueParser`]s
808 #[derive(Copy, Clone, Debug)]
809 #[non_exhaustive]
810 pub struct PathBufValueParser {}
811 
812 impl PathBufValueParser {
813     /// Implementation for [`ValueParser::path_buf`]
new() -> Self814     pub fn new() -> Self {
815         Self {}
816     }
817 }
818 
819 impl TypedValueParser for PathBufValueParser {
820     type Value = std::path::PathBuf;
821 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>822     fn parse_ref(
823         &self,
824         cmd: &crate::Command,
825         arg: Option<&crate::Arg>,
826         value: &std::ffi::OsStr,
827     ) -> Result<Self::Value, crate::Error> {
828         TypedValueParser::parse(self, cmd, arg, value.to_owned())
829     }
830 
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<Self::Value, crate::Error>831     fn parse(
832         &self,
833         cmd: &crate::Command,
834         arg: Option<&crate::Arg>,
835         value: std::ffi::OsString,
836     ) -> Result<Self::Value, crate::Error> {
837         if value.is_empty() {
838             return Err(crate::Error::empty_value(
839                 cmd,
840                 &[],
841                 arg.map(ToString::to_string)
842                     .unwrap_or_else(|| "...".to_owned()),
843             ));
844         }
845         Ok(Self::Value::from(value))
846     }
847 }
848 
849 impl Default for PathBufValueParser {
default() -> Self850     fn default() -> Self {
851         Self::new()
852     }
853 }
854 
855 /// Parse an [`ValueEnum`][crate::ValueEnum] value.
856 ///
857 /// See also:
858 /// - [`PossibleValuesParser`]
859 ///
860 /// # Example
861 ///
862 /// ```rust
863 /// # use std::ffi::OsStr;
864 /// # use clap::builder::TypedValueParser;
865 /// # let cmd = clap::Command::new("test");
866 /// # let arg = None;
867 ///
868 /// #[derive(Copy, Clone, Debug, PartialEq, Eq)]
869 /// enum ColorChoice {
870 ///     Always,
871 ///     Auto,
872 ///     Never,
873 /// }
874 ///
875 /// impl clap::ValueEnum for ColorChoice {
876 ///     fn value_variants<'a>() -> &'a [Self] {
877 ///         &[Self::Always, Self::Auto, Self::Never]
878 ///     }
879 ///
880 ///     fn to_possible_value<'a>(&self) -> Option<clap::PossibleValue<'a>> {
881 ///         match self {
882 ///             Self::Always => Some(clap::PossibleValue::new("always")),
883 ///             Self::Auto => Some(clap::PossibleValue::new("auto")),
884 ///             Self::Never => Some(clap::PossibleValue::new("never")),
885 ///         }
886 ///     }
887 /// }
888 ///
889 /// // Usage
890 /// let mut cmd = clap::Command::new("raw")
891 ///     .arg(
892 ///         clap::Arg::new("color")
893 ///             .value_parser(clap::builder::EnumValueParser::<ColorChoice>::new())
894 ///             .required(true)
895 ///     );
896 ///
897 /// let m = cmd.try_get_matches_from_mut(["cmd", "always"]).unwrap();
898 /// let port: ColorChoice = *m.get_one("color")
899 ///     .expect("required");
900 /// assert_eq!(port, ColorChoice::Always);
901 ///
902 /// // Semantics
903 /// let value_parser = clap::builder::EnumValueParser::<ColorChoice>::new();
904 /// // or
905 /// let value_parser = clap::value_parser!(ColorChoice);
906 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
907 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
908 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("always")).unwrap(), ColorChoice::Always);
909 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("auto")).unwrap(), ColorChoice::Auto);
910 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("never")).unwrap(), ColorChoice::Never);
911 /// ```
912 #[derive(Clone, Debug)]
913 pub struct EnumValueParser<E: crate::ValueEnum + Clone + Send + Sync + 'static>(
914     std::marker::PhantomData<E>,
915 );
916 
917 impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> EnumValueParser<E> {
918     /// Parse an [`ValueEnum`][crate::ValueEnum]
new() -> Self919     pub fn new() -> Self {
920         let phantom: std::marker::PhantomData<E> = Default::default();
921         Self(phantom)
922     }
923 }
924 
925 impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> TypedValueParser for EnumValueParser<E> {
926     type Value = E;
927 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>928     fn parse_ref(
929         &self,
930         cmd: &crate::Command,
931         arg: Option<&crate::Arg>,
932         value: &std::ffi::OsStr,
933     ) -> Result<Self::Value, crate::Error> {
934         let ignore_case = arg.map(|a| a.is_ignore_case_set()).unwrap_or(false);
935         let possible_vals = || {
936             E::value_variants()
937                 .iter()
938                 .filter_map(|v| v.to_possible_value())
939                 .filter(|v| !v.is_hide_set())
940                 .map(|v| v.get_name())
941                 .collect::<Vec<_>>()
942         };
943 
944         let value = value.to_str().ok_or_else(|| {
945             crate::Error::invalid_value(
946                 cmd,
947                 value.to_string_lossy().into_owned(),
948                 &possible_vals(),
949                 arg.map(ToString::to_string)
950                     .unwrap_or_else(|| "...".to_owned()),
951             )
952         })?;
953         let value = E::value_variants()
954             .iter()
955             .find(|v| {
956                 v.to_possible_value()
957                     .expect("ValueEnum::value_variants contains only values with a corresponding ValueEnum::to_possible_value")
958                     .matches(value, ignore_case)
959             })
960             .ok_or_else(|| {
961             crate::Error::invalid_value(
962                 cmd,
963                 value.to_owned(),
964                 &possible_vals(),
965                 arg.map(ToString::to_string)
966                     .unwrap_or_else(|| "...".to_owned()),
967             )
968             })?
969             .clone();
970         Ok(value)
971     }
972 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>973     fn possible_values(
974         &self,
975     ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>> {
976         Some(Box::new(
977             E::value_variants()
978                 .iter()
979                 .filter_map(|v| v.to_possible_value()),
980         ))
981     }
982 }
983 
984 impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> Default for EnumValueParser<E> {
default() -> Self985     fn default() -> Self {
986         Self::new()
987     }
988 }
989 
990 /// Verify the value is from an enumerated set of [`PossibleValue`][crate::PossibleValue].
991 ///
992 /// See also:
993 /// - [`EnumValueParser`]
994 ///
995 /// # Example
996 ///
997 /// Usage:
998 /// ```rust
999 /// let mut cmd = clap::Command::new("raw")
1000 ///     .arg(
1001 ///         clap::Arg::new("color")
1002 ///             .value_parser(clap::builder::PossibleValuesParser::new(["always", "auto", "never"]))
1003 ///             .required(true)
1004 ///     );
1005 ///
1006 /// let m = cmd.try_get_matches_from_mut(["cmd", "always"]).unwrap();
1007 /// let port: &String = m.get_one("color")
1008 ///     .expect("required");
1009 /// assert_eq!(port, "always");
1010 /// ```
1011 ///
1012 /// Semantics:
1013 /// ```rust
1014 /// # use std::ffi::OsStr;
1015 /// # use clap::builder::TypedValueParser;
1016 /// # let cmd = clap::Command::new("test");
1017 /// # let arg = None;
1018 /// let value_parser = clap::builder::PossibleValuesParser::new(["always", "auto", "never"]);
1019 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
1020 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1021 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("always")).unwrap(), "always");
1022 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("auto")).unwrap(), "auto");
1023 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("never")).unwrap(), "never");
1024 /// ```
1025 #[derive(Clone, Debug)]
1026 pub struct PossibleValuesParser(Vec<super::PossibleValue<'static>>);
1027 
1028 impl PossibleValuesParser {
1029     /// Verify the value is from an enumerated set pf [`PossibleValue`][crate::PossibleValue].
new(values: impl Into<PossibleValuesParser>) -> Self1030     pub fn new(values: impl Into<PossibleValuesParser>) -> Self {
1031         values.into()
1032     }
1033 }
1034 
1035 impl TypedValueParser for PossibleValuesParser {
1036     type Value = String;
1037 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1038     fn parse_ref(
1039         &self,
1040         cmd: &crate::Command,
1041         arg: Option<&crate::Arg>,
1042         value: &std::ffi::OsStr,
1043     ) -> Result<Self::Value, crate::Error> {
1044         TypedValueParser::parse(self, cmd, arg, value.to_owned())
1045     }
1046 
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<String, crate::Error>1047     fn parse(
1048         &self,
1049         cmd: &crate::Command,
1050         arg: Option<&crate::Arg>,
1051         value: std::ffi::OsString,
1052     ) -> Result<String, crate::Error> {
1053         let value = value.into_string().map_err(|_| {
1054             crate::Error::invalid_utf8(
1055                 cmd,
1056                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1057             )
1058         })?;
1059 
1060         let ignore_case = arg.map(|a| a.is_ignore_case_set()).unwrap_or(false);
1061         if self.0.iter().any(|v| v.matches(&value, ignore_case)) {
1062             Ok(value)
1063         } else {
1064             let possible_vals = self
1065                 .0
1066                 .iter()
1067                 .filter(|v| !v.is_hide_set())
1068                 .map(crate::builder::PossibleValue::get_name)
1069                 .collect::<Vec<_>>();
1070 
1071             Err(crate::Error::invalid_value(
1072                 cmd,
1073                 value,
1074                 &possible_vals,
1075                 arg.map(ToString::to_string)
1076                     .unwrap_or_else(|| "...".to_owned()),
1077             ))
1078         }
1079     }
1080 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>1081     fn possible_values(
1082         &self,
1083     ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>> {
1084         Some(Box::new(self.0.iter().cloned()))
1085     }
1086 }
1087 
1088 impl<I, T> From<I> for PossibleValuesParser
1089 where
1090     I: IntoIterator<Item = T>,
1091     T: Into<super::PossibleValue<'static>>,
1092 {
from(values: I) -> Self1093     fn from(values: I) -> Self {
1094         Self(values.into_iter().map(|t| t.into()).collect())
1095     }
1096 }
1097 
1098 /// Parse number that fall within a range of values
1099 ///
1100 /// # Example
1101 ///
1102 /// Usage:
1103 /// ```rust
1104 /// let mut cmd = clap::Command::new("raw")
1105 ///     .arg(
1106 ///         clap::Arg::new("port")
1107 ///             .long("port")
1108 ///             .value_parser(clap::value_parser!(u16).range(3000..))
1109 ///             .takes_value(true)
1110 ///             .required(true)
1111 ///     );
1112 ///
1113 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
1114 /// let port: u16 = *m.get_one("port")
1115 ///     .expect("required");
1116 /// assert_eq!(port, 3001);
1117 /// ```
1118 ///
1119 /// Semantics:
1120 /// ```rust
1121 /// # use std::ffi::OsStr;
1122 /// # use clap::builder::TypedValueParser;
1123 /// # let cmd = clap::Command::new("test");
1124 /// # let arg = None;
1125 /// let value_parser = clap::builder::RangedI64ValueParser::<i32>::new().range(-1..200);
1126 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
1127 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1128 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("-200")).is_err());
1129 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("300")).is_err());
1130 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("-1")).unwrap(), -1);
1131 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), 0);
1132 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("50")).unwrap(), 50);
1133 /// ```
1134 #[derive(Copy, Clone, Debug)]
1135 pub struct RangedI64ValueParser<T: std::convert::TryFrom<i64> + Clone + Send + Sync = i64> {
1136     bounds: (std::ops::Bound<i64>, std::ops::Bound<i64>),
1137     target: std::marker::PhantomData<T>,
1138 }
1139 
1140 impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> RangedI64ValueParser<T> {
1141     /// Select full range of `i64`
new() -> Self1142     pub fn new() -> Self {
1143         Self::from(..)
1144     }
1145 
1146     /// Narrow the supported range
range<B: RangeBounds<i64>>(mut self, range: B) -> Self1147     pub fn range<B: RangeBounds<i64>>(mut self, range: B) -> Self {
1148         // Consideration: when the user does `value_parser!(u8).range()`
1149         // - Avoid programming mistakes by accidentally expanding the range
1150         // - Make it convenient to limit the range like with `..10`
1151         let start = match range.start_bound() {
1152             l @ std::ops::Bound::Included(i) => {
1153                 debug_assert!(
1154                     self.bounds.contains(i),
1155                     "{} must be in {:?}",
1156                     i,
1157                     self.bounds
1158                 );
1159                 l.cloned()
1160             }
1161             l @ std::ops::Bound::Excluded(i) => {
1162                 debug_assert!(
1163                     self.bounds.contains(&i.saturating_add(1)),
1164                     "{} must be in {:?}",
1165                     i,
1166                     self.bounds
1167                 );
1168                 l.cloned()
1169             }
1170             std::ops::Bound::Unbounded => self.bounds.start_bound().cloned(),
1171         };
1172         let end = match range.end_bound() {
1173             l @ std::ops::Bound::Included(i) => {
1174                 debug_assert!(
1175                     self.bounds.contains(i),
1176                     "{} must be in {:?}",
1177                     i,
1178                     self.bounds
1179                 );
1180                 l.cloned()
1181             }
1182             l @ std::ops::Bound::Excluded(i) => {
1183                 debug_assert!(
1184                     self.bounds.contains(&i.saturating_sub(1)),
1185                     "{} must be in {:?}",
1186                     i,
1187                     self.bounds
1188                 );
1189                 l.cloned()
1190             }
1191             std::ops::Bound::Unbounded => self.bounds.end_bound().cloned(),
1192         };
1193         self.bounds = (start, end);
1194         self
1195     }
1196 
format_bounds(&self) -> String1197     fn format_bounds(&self) -> String {
1198         let mut result = match self.bounds.0 {
1199             std::ops::Bound::Included(i) => i.to_string(),
1200             std::ops::Bound::Excluded(i) => i.saturating_add(1).to_string(),
1201             std::ops::Bound::Unbounded => i64::MIN.to_string(),
1202         };
1203         result.push_str("..");
1204         match self.bounds.1 {
1205             std::ops::Bound::Included(i) => {
1206                 result.push('=');
1207                 result.push_str(&i.to_string());
1208             }
1209             std::ops::Bound::Excluded(i) => {
1210                 result.push_str(&i.to_string());
1211             }
1212             std::ops::Bound::Unbounded => {
1213                 result.push_str(&i64::MAX.to_string());
1214             }
1215         }
1216         result
1217     }
1218 }
1219 
1220 impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync + 'static> TypedValueParser
1221     for RangedI64ValueParser<T>
1222 where
1223     <T as std::convert::TryFrom<i64>>::Error: Send + Sync + 'static + std::error::Error + ToString,
1224 {
1225     type Value = T;
1226 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, raw_value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1227     fn parse_ref(
1228         &self,
1229         cmd: &crate::Command,
1230         arg: Option<&crate::Arg>,
1231         raw_value: &std::ffi::OsStr,
1232     ) -> Result<Self::Value, crate::Error> {
1233         let value = raw_value.to_str().ok_or_else(|| {
1234             crate::Error::invalid_utf8(
1235                 cmd,
1236                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1237             )
1238         })?;
1239         let value = value.parse::<i64>().map_err(|err| {
1240             let arg = arg
1241                 .map(|a| a.to_string())
1242                 .unwrap_or_else(|| "...".to_owned());
1243             crate::Error::value_validation(
1244                 arg,
1245                 raw_value.to_string_lossy().into_owned(),
1246                 err.into(),
1247             )
1248             .with_cmd(cmd)
1249         })?;
1250         if !self.bounds.contains(&value) {
1251             let arg = arg
1252                 .map(|a| a.to_string())
1253                 .unwrap_or_else(|| "...".to_owned());
1254             return Err(crate::Error::value_validation(
1255                 arg,
1256                 raw_value.to_string_lossy().into_owned(),
1257                 format!("{} is not in {}", value, self.format_bounds()).into(),
1258             )
1259             .with_cmd(cmd));
1260         }
1261 
1262         let value: Result<Self::Value, _> = value.try_into();
1263         let value = value.map_err(|err| {
1264             let arg = arg
1265                 .map(|a| a.to_string())
1266                 .unwrap_or_else(|| "...".to_owned());
1267             crate::Error::value_validation(
1268                 arg,
1269                 raw_value.to_string_lossy().into_owned(),
1270                 err.into(),
1271             )
1272             .with_cmd(cmd)
1273         })?;
1274 
1275         Ok(value)
1276     }
1277 }
1278 
1279 impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync, B: RangeBounds<i64>> From<B>
1280     for RangedI64ValueParser<T>
1281 {
from(range: B) -> Self1282     fn from(range: B) -> Self {
1283         Self {
1284             bounds: (range.start_bound().cloned(), range.end_bound().cloned()),
1285             target: Default::default(),
1286         }
1287     }
1288 }
1289 
1290 impl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> Default for RangedI64ValueParser<T> {
default() -> Self1291     fn default() -> Self {
1292         Self::new()
1293     }
1294 }
1295 
1296 /// Parse number that fall within a range of values
1297 ///
1298 /// # Example
1299 ///
1300 /// Usage:
1301 /// ```rust
1302 /// let mut cmd = clap::Command::new("raw")
1303 ///     .arg(
1304 ///         clap::Arg::new("port")
1305 ///             .long("port")
1306 ///             .value_parser(clap::value_parser!(u64).range(3000..))
1307 ///             .takes_value(true)
1308 ///             .required(true)
1309 ///     );
1310 ///
1311 /// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap();
1312 /// let port: u64 = *m.get_one("port")
1313 ///     .expect("required");
1314 /// assert_eq!(port, 3001);
1315 /// ```
1316 ///
1317 /// Semantics:
1318 /// ```rust
1319 /// # use std::ffi::OsStr;
1320 /// # use clap::builder::TypedValueParser;
1321 /// # let cmd = clap::Command::new("test");
1322 /// # let arg = None;
1323 /// let value_parser = clap::builder::RangedU64ValueParser::<u32>::new().range(0..200);
1324 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
1325 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1326 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("-200")).is_err());
1327 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("300")).is_err());
1328 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("-1")).is_err());
1329 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), 0);
1330 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("50")).unwrap(), 50);
1331 /// ```
1332 #[derive(Copy, Clone, Debug)]
1333 pub struct RangedU64ValueParser<T: std::convert::TryFrom<u64> = u64> {
1334     bounds: (std::ops::Bound<u64>, std::ops::Bound<u64>),
1335     target: std::marker::PhantomData<T>,
1336 }
1337 
1338 impl<T: std::convert::TryFrom<u64>> RangedU64ValueParser<T> {
1339     /// Select full range of `u64`
new() -> Self1340     pub fn new() -> Self {
1341         Self::from(..)
1342     }
1343 
1344     /// Narrow the supported range
range<B: RangeBounds<u64>>(mut self, range: B) -> Self1345     pub fn range<B: RangeBounds<u64>>(mut self, range: B) -> Self {
1346         // Consideration: when the user does `value_parser!(u8).range()`
1347         // - Avoid programming mistakes by accidentally expanding the range
1348         // - Make it convenient to limit the range like with `..10`
1349         let start = match range.start_bound() {
1350             l @ std::ops::Bound::Included(i) => {
1351                 debug_assert!(
1352                     self.bounds.contains(i),
1353                     "{} must be in {:?}",
1354                     i,
1355                     self.bounds
1356                 );
1357                 l.cloned()
1358             }
1359             l @ std::ops::Bound::Excluded(i) => {
1360                 debug_assert!(
1361                     self.bounds.contains(&i.saturating_add(1)),
1362                     "{} must be in {:?}",
1363                     i,
1364                     self.bounds
1365                 );
1366                 l.cloned()
1367             }
1368             std::ops::Bound::Unbounded => self.bounds.start_bound().cloned(),
1369         };
1370         let end = match range.end_bound() {
1371             l @ std::ops::Bound::Included(i) => {
1372                 debug_assert!(
1373                     self.bounds.contains(i),
1374                     "{} must be in {:?}",
1375                     i,
1376                     self.bounds
1377                 );
1378                 l.cloned()
1379             }
1380             l @ std::ops::Bound::Excluded(i) => {
1381                 debug_assert!(
1382                     self.bounds.contains(&i.saturating_sub(1)),
1383                     "{} must be in {:?}",
1384                     i,
1385                     self.bounds
1386                 );
1387                 l.cloned()
1388             }
1389             std::ops::Bound::Unbounded => self.bounds.end_bound().cloned(),
1390         };
1391         self.bounds = (start, end);
1392         self
1393     }
1394 
format_bounds(&self) -> String1395     fn format_bounds(&self) -> String {
1396         let mut result = match self.bounds.0 {
1397             std::ops::Bound::Included(i) => i.to_string(),
1398             std::ops::Bound::Excluded(i) => i.saturating_add(1).to_string(),
1399             std::ops::Bound::Unbounded => u64::MIN.to_string(),
1400         };
1401         result.push_str("..");
1402         match self.bounds.1 {
1403             std::ops::Bound::Included(i) => {
1404                 result.push('=');
1405                 result.push_str(&i.to_string());
1406             }
1407             std::ops::Bound::Excluded(i) => {
1408                 result.push_str(&i.to_string());
1409             }
1410             std::ops::Bound::Unbounded => {
1411                 result.push_str(&u64::MAX.to_string());
1412             }
1413         }
1414         result
1415     }
1416 }
1417 
1418 impl<T: std::convert::TryFrom<u64> + Clone + Send + Sync + 'static> TypedValueParser
1419     for RangedU64ValueParser<T>
1420 where
1421     <T as std::convert::TryFrom<u64>>::Error: Send + Sync + 'static + std::error::Error + ToString,
1422 {
1423     type Value = T;
1424 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, raw_value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1425     fn parse_ref(
1426         &self,
1427         cmd: &crate::Command,
1428         arg: Option<&crate::Arg>,
1429         raw_value: &std::ffi::OsStr,
1430     ) -> Result<Self::Value, crate::Error> {
1431         let value = raw_value.to_str().ok_or_else(|| {
1432             crate::Error::invalid_utf8(
1433                 cmd,
1434                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1435             )
1436         })?;
1437         let value = value.parse::<u64>().map_err(|err| {
1438             let arg = arg
1439                 .map(|a| a.to_string())
1440                 .unwrap_or_else(|| "...".to_owned());
1441             crate::Error::value_validation(
1442                 arg,
1443                 raw_value.to_string_lossy().into_owned(),
1444                 err.into(),
1445             )
1446             .with_cmd(cmd)
1447         })?;
1448         if !self.bounds.contains(&value) {
1449             let arg = arg
1450                 .map(|a| a.to_string())
1451                 .unwrap_or_else(|| "...".to_owned());
1452             return Err(crate::Error::value_validation(
1453                 arg,
1454                 raw_value.to_string_lossy().into_owned(),
1455                 format!("{} is not in {}", value, self.format_bounds()).into(),
1456             )
1457             .with_cmd(cmd));
1458         }
1459 
1460         let value: Result<Self::Value, _> = value.try_into();
1461         let value = value.map_err(|err| {
1462             let arg = arg
1463                 .map(|a| a.to_string())
1464                 .unwrap_or_else(|| "...".to_owned());
1465             crate::Error::value_validation(
1466                 arg,
1467                 raw_value.to_string_lossy().into_owned(),
1468                 err.into(),
1469             )
1470             .with_cmd(cmd)
1471         })?;
1472 
1473         Ok(value)
1474     }
1475 }
1476 
1477 impl<T: std::convert::TryFrom<u64>, B: RangeBounds<u64>> From<B> for RangedU64ValueParser<T> {
from(range: B) -> Self1478     fn from(range: B) -> Self {
1479         Self {
1480             bounds: (range.start_bound().cloned(), range.end_bound().cloned()),
1481             target: Default::default(),
1482         }
1483     }
1484 }
1485 
1486 impl<T: std::convert::TryFrom<u64>> Default for RangedU64ValueParser<T> {
default() -> Self1487     fn default() -> Self {
1488         Self::new()
1489     }
1490 }
1491 
1492 /// Implementation for [`ValueParser::bool`]
1493 ///
1494 /// Useful for composing new [`TypedValueParser`]s
1495 #[derive(Copy, Clone, Debug)]
1496 #[non_exhaustive]
1497 pub struct BoolValueParser {}
1498 
1499 impl BoolValueParser {
1500     /// Implementation for [`ValueParser::bool`]
new() -> Self1501     pub fn new() -> Self {
1502         Self {}
1503     }
1504 
possible_values() -> impl Iterator<Item = crate::PossibleValue<'static>>1505     fn possible_values() -> impl Iterator<Item = crate::PossibleValue<'static>> {
1506         ["true", "false"]
1507             .iter()
1508             .copied()
1509             .map(crate::PossibleValue::new)
1510     }
1511 }
1512 
1513 impl TypedValueParser for BoolValueParser {
1514     type Value = bool;
1515 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1516     fn parse_ref(
1517         &self,
1518         cmd: &crate::Command,
1519         arg: Option<&crate::Arg>,
1520         value: &std::ffi::OsStr,
1521     ) -> Result<Self::Value, crate::Error> {
1522         let value = if value == std::ffi::OsStr::new("true") {
1523             true
1524         } else if value == std::ffi::OsStr::new("false") {
1525             false
1526         } else {
1527             // Intentionally showing hidden as we hide all of them
1528             let possible_vals = Self::possible_values()
1529                 .map(|v| v.get_name())
1530                 .collect::<Vec<_>>();
1531 
1532             return Err(crate::Error::invalid_value(
1533                 cmd,
1534                 value.to_string_lossy().into_owned(),
1535                 &possible_vals,
1536                 arg.map(ToString::to_string)
1537                     .unwrap_or_else(|| "...".to_owned()),
1538             ));
1539         };
1540         Ok(value)
1541     }
1542 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>1543     fn possible_values(
1544         &self,
1545     ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>> {
1546         Some(Box::new(Self::possible_values()))
1547     }
1548 }
1549 
1550 impl Default for BoolValueParser {
default() -> Self1551     fn default() -> Self {
1552         Self::new()
1553     }
1554 }
1555 
1556 /// Parse false-like string values, everything else is `true`
1557 ///
1558 /// See also:
1559 /// - [`ValueParser::bool`] for assuming non-false is true
1560 /// - [`BoolishValueParser`] for different human readable bool representations
1561 ///
1562 /// # Example
1563 ///
1564 /// Usage:
1565 /// ```rust
1566 /// let mut cmd = clap::Command::new("raw")
1567 ///     .arg(
1568 ///         clap::Arg::new("append")
1569 ///             .value_parser(clap::builder::FalseyValueParser::new())
1570 ///             .required(true)
1571 ///     );
1572 ///
1573 /// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap();
1574 /// let port: bool = *m.get_one("append")
1575 ///     .expect("required");
1576 /// assert_eq!(port, true);
1577 /// ```
1578 ///
1579 /// Semantics:
1580 /// ```rust
1581 /// # use std::ffi::OsStr;
1582 /// # use clap::builder::TypedValueParser;
1583 /// # let cmd = clap::Command::new("test");
1584 /// # let arg = None;
1585 /// let value_parser = clap::builder::FalseyValueParser::new();
1586 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).unwrap(), true);
1587 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("100")).unwrap(), true);
1588 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).unwrap(), false);
1589 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("false")).unwrap(), false);
1590 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("No")).unwrap(), false);
1591 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("oFF")).unwrap(), false);
1592 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), false);
1593 /// ```
1594 #[derive(Copy, Clone, Debug)]
1595 #[non_exhaustive]
1596 pub struct FalseyValueParser {}
1597 
1598 impl FalseyValueParser {
1599     /// Parse false-like string values, everything else is `true`
new() -> Self1600     pub fn new() -> Self {
1601         Self {}
1602     }
1603 
possible_values() -> impl Iterator<Item = crate::PossibleValue<'static>>1604     fn possible_values() -> impl Iterator<Item = crate::PossibleValue<'static>> {
1605         crate::util::TRUE_LITERALS
1606             .iter()
1607             .chain(crate::util::FALSE_LITERALS.iter())
1608             .copied()
1609             .map(|l| crate::PossibleValue::new(l).hide(l != "true" && l != "false"))
1610     }
1611 }
1612 
1613 impl TypedValueParser for FalseyValueParser {
1614     type Value = bool;
1615 
parse_ref( &self, cmd: &crate::Command, _arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1616     fn parse_ref(
1617         &self,
1618         cmd: &crate::Command,
1619         _arg: Option<&crate::Arg>,
1620         value: &std::ffi::OsStr,
1621     ) -> Result<Self::Value, crate::Error> {
1622         let value = value.to_str().ok_or_else(|| {
1623             crate::Error::invalid_utf8(
1624                 cmd,
1625                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1626             )
1627         })?;
1628         let value = if value.is_empty() {
1629             false
1630         } else {
1631             crate::util::str_to_bool(value).unwrap_or(true)
1632         };
1633         Ok(value)
1634     }
1635 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>1636     fn possible_values(
1637         &self,
1638     ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>> {
1639         Some(Box::new(Self::possible_values()))
1640     }
1641 }
1642 
1643 impl Default for FalseyValueParser {
default() -> Self1644     fn default() -> Self {
1645         Self::new()
1646     }
1647 }
1648 
1649 /// Parse bool-like string values, everything else is `true`
1650 ///
1651 /// See also:
1652 /// - [`ValueParser::bool`] for different human readable bool representations
1653 /// - [`FalseyValueParser`] for assuming non-false is true
1654 ///
1655 /// # Example
1656 ///
1657 /// Usage:
1658 /// ```rust
1659 /// let mut cmd = clap::Command::new("raw")
1660 ///     .arg(
1661 ///         clap::Arg::new("append")
1662 ///             .value_parser(clap::builder::BoolishValueParser::new())
1663 ///             .required(true)
1664 ///     );
1665 ///
1666 /// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap();
1667 /// let port: bool = *m.get_one("append")
1668 ///     .expect("required");
1669 /// assert_eq!(port, true);
1670 /// ```
1671 ///
1672 /// Semantics:
1673 /// ```rust
1674 /// # use std::ffi::OsStr;
1675 /// # use clap::builder::TypedValueParser;
1676 /// # let cmd = clap::Command::new("test");
1677 /// # let arg = None;
1678 /// let value_parser = clap::builder::BoolishValueParser::new();
1679 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err());
1680 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1681 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("100")).is_err());
1682 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("true")).unwrap(), true);
1683 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("Yes")).unwrap(), true);
1684 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("oN")).unwrap(), true);
1685 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("1")).unwrap(), true);
1686 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("false")).unwrap(), false);
1687 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("No")).unwrap(), false);
1688 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("oFF")).unwrap(), false);
1689 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), false);
1690 /// ```
1691 #[derive(Copy, Clone, Debug)]
1692 #[non_exhaustive]
1693 pub struct BoolishValueParser {}
1694 
1695 impl BoolishValueParser {
1696     /// Parse bool-like string values, everything else is `true`
new() -> Self1697     pub fn new() -> Self {
1698         Self {}
1699     }
1700 
possible_values() -> impl Iterator<Item = crate::PossibleValue<'static>>1701     fn possible_values() -> impl Iterator<Item = crate::PossibleValue<'static>> {
1702         crate::util::TRUE_LITERALS
1703             .iter()
1704             .chain(crate::util::FALSE_LITERALS.iter())
1705             .copied()
1706             .map(|l| crate::PossibleValue::new(l).hide(l != "true" && l != "false"))
1707     }
1708 }
1709 
1710 impl TypedValueParser for BoolishValueParser {
1711     type Value = bool;
1712 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1713     fn parse_ref(
1714         &self,
1715         cmd: &crate::Command,
1716         arg: Option<&crate::Arg>,
1717         value: &std::ffi::OsStr,
1718     ) -> Result<Self::Value, crate::Error> {
1719         let value = value.to_str().ok_or_else(|| {
1720             crate::Error::invalid_utf8(
1721                 cmd,
1722                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1723             )
1724         })?;
1725         let value = crate::util::str_to_bool(value).ok_or_else(|| {
1726             let arg = arg
1727                 .map(|a| a.to_string())
1728                 .unwrap_or_else(|| "...".to_owned());
1729             crate::Error::value_validation(arg, value.to_owned(), "value was not a boolean".into())
1730                 .with_cmd(cmd)
1731         })?;
1732         Ok(value)
1733     }
1734 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>>1735     fn possible_values(
1736         &self,
1737     ) -> Option<Box<dyn Iterator<Item = crate::PossibleValue<'static>> + '_>> {
1738         Some(Box::new(Self::possible_values()))
1739     }
1740 }
1741 
1742 impl Default for BoolishValueParser {
default() -> Self1743     fn default() -> Self {
1744         Self::new()
1745     }
1746 }
1747 
1748 /// Parse non-empty string values
1749 ///
1750 /// See also:
1751 /// - [`ValueParser::string`]
1752 ///
1753 /// # Example
1754 ///
1755 /// Usage:
1756 /// ```rust
1757 /// let mut cmd = clap::Command::new("raw")
1758 ///     .arg(
1759 ///         clap::Arg::new("append")
1760 ///             .value_parser(clap::builder::NonEmptyStringValueParser::new())
1761 ///             .required(true)
1762 ///     );
1763 ///
1764 /// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap();
1765 /// let port: &String = m.get_one("append")
1766 ///     .expect("required");
1767 /// assert_eq!(port, "true");
1768 /// ```
1769 ///
1770 /// Semantics:
1771 /// ```rust
1772 /// # use std::ffi::OsStr;
1773 /// # use clap::builder::TypedValueParser;
1774 /// # let cmd = clap::Command::new("test");
1775 /// # let arg = None;
1776 /// let value_parser = clap::builder::NonEmptyStringValueParser::new();
1777 /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).unwrap(), "random");
1778 /// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err());
1779 /// ```
1780 #[derive(Copy, Clone, Debug)]
1781 #[non_exhaustive]
1782 pub struct NonEmptyStringValueParser {}
1783 
1784 impl NonEmptyStringValueParser {
1785     /// Parse non-empty string values
new() -> Self1786     pub fn new() -> Self {
1787         Self {}
1788     }
1789 }
1790 
1791 impl TypedValueParser for NonEmptyStringValueParser {
1792     type Value = String;
1793 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1794     fn parse_ref(
1795         &self,
1796         cmd: &crate::Command,
1797         arg: Option<&crate::Arg>,
1798         value: &std::ffi::OsStr,
1799     ) -> Result<Self::Value, crate::Error> {
1800         if value.is_empty() {
1801             return Err(crate::Error::empty_value(
1802                 cmd,
1803                 &[],
1804                 arg.map(ToString::to_string)
1805                     .unwrap_or_else(|| "...".to_owned()),
1806             ));
1807         }
1808         let value = value.to_str().ok_or_else(|| {
1809             crate::Error::invalid_utf8(
1810                 cmd,
1811                 crate::output::Usage::new(cmd).create_usage_with_title(&[]),
1812             )
1813         })?;
1814         Ok(value.to_owned())
1815     }
1816 }
1817 
1818 impl Default for NonEmptyStringValueParser {
default() -> Self1819     fn default() -> Self {
1820         Self::new()
1821     }
1822 }
1823 
1824 /// Adapt a `TypedValueParser` from one value to another
1825 ///
1826 /// See [`TypedValueParser::map`]
1827 #[derive(Clone, Debug)]
1828 pub struct MapValueParser<P, F> {
1829     parser: P,
1830     func: F,
1831 }
1832 
1833 impl<P, F> MapValueParser<P, F> {
new(parser: P, func: F) -> Self1834     fn new(parser: P, func: F) -> Self {
1835         Self { parser, func }
1836     }
1837 }
1838 
1839 impl<P, F, T> TypedValueParser for MapValueParser<P, F>
1840 where
1841     P: TypedValueParser,
1842     P::Value: Send + Sync + Clone,
1843     F: Fn(P::Value) -> T + Clone + Send + Sync + 'static,
1844     T: Send + Sync + Clone,
1845 {
1846     type Value = T;
1847 
parse_ref( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, crate::Error>1848     fn parse_ref(
1849         &self,
1850         cmd: &crate::Command,
1851         arg: Option<&crate::Arg>,
1852         value: &std::ffi::OsStr,
1853     ) -> Result<Self::Value, crate::Error> {
1854         let value = self.parser.parse_ref(cmd, arg, value)?;
1855         let value = (self.func)(value);
1856         Ok(value)
1857     }
1858 
parse( &self, cmd: &crate::Command, arg: Option<&crate::Arg>, value: std::ffi::OsString, ) -> Result<Self::Value, crate::Error>1859     fn parse(
1860         &self,
1861         cmd: &crate::Command,
1862         arg: Option<&crate::Arg>,
1863         value: std::ffi::OsString,
1864     ) -> Result<Self::Value, crate::Error> {
1865         let value = self.parser.parse(cmd, arg, value)?;
1866         let value = (self.func)(value);
1867         Ok(value)
1868     }
1869 
possible_values( &self, ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue<'static>> + '_>>1870     fn possible_values(
1871         &self,
1872     ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue<'static>> + '_>> {
1873         self.parser.possible_values()
1874     }
1875 }
1876 
1877 /// Register a type with [value_parser!][crate::value_parser!]
1878 ///
1879 /// # Example
1880 ///
1881 /// ```rust
1882 /// #[derive(Copy, Clone, Debug)]
1883 /// pub struct Custom(u32);
1884 ///
1885 /// impl clap::builder::ValueParserFactory for Custom {
1886 ///     type Parser = CustomValueParser;
1887 ///     fn value_parser() -> Self::Parser {
1888 ///         CustomValueParser
1889 ///     }
1890 /// }
1891 ///
1892 /// #[derive(Clone, Debug)]
1893 /// pub struct CustomValueParser;
1894 /// impl clap::builder::TypedValueParser for CustomValueParser {
1895 ///     type Value = Custom;
1896 ///
1897 ///     fn parse_ref(
1898 ///         &self,
1899 ///         cmd: &clap::Command,
1900 ///         arg: Option<&clap::Arg>,
1901 ///         value: &std::ffi::OsStr,
1902 ///     ) -> Result<Self::Value, clap::Error> {
1903 ///         let inner = clap::value_parser!(u32);
1904 ///         let val = inner.parse_ref(cmd, arg, value)?;
1905 ///         Ok(Custom(val))
1906 ///     }
1907 /// }
1908 ///
1909 /// let parser: CustomValueParser = clap::value_parser!(Custom);
1910 /// ```
1911 pub trait ValueParserFactory {
1912     /// Generated parser, usually [`ValueParser`].
1913     ///
1914     /// It should at least be a type that supports `Into<ValueParser>`.  A non-`ValueParser` type
1915     /// allows the caller to do further initialization on the parser.
1916     type Parser;
1917 
1918     /// Create the specified [`Self::Parser`]
value_parser() -> Self::Parser1919     fn value_parser() -> Self::Parser;
1920 }
1921 impl ValueParserFactory for String {
1922     type Parser = ValueParser;
value_parser() -> Self::Parser1923     fn value_parser() -> Self::Parser {
1924         ValueParser::string()
1925     }
1926 }
1927 impl ValueParserFactory for std::ffi::OsString {
1928     type Parser = ValueParser;
value_parser() -> Self::Parser1929     fn value_parser() -> Self::Parser {
1930         ValueParser::os_string()
1931     }
1932 }
1933 impl ValueParserFactory for std::path::PathBuf {
1934     type Parser = ValueParser;
value_parser() -> Self::Parser1935     fn value_parser() -> Self::Parser {
1936         ValueParser::path_buf()
1937     }
1938 }
1939 impl ValueParserFactory for bool {
1940     type Parser = ValueParser;
value_parser() -> Self::Parser1941     fn value_parser() -> Self::Parser {
1942         ValueParser::bool()
1943     }
1944 }
1945 impl ValueParserFactory for u8 {
1946     type Parser = RangedI64ValueParser<u8>;
value_parser() -> Self::Parser1947     fn value_parser() -> Self::Parser {
1948         let start: i64 = u8::MIN.into();
1949         let end: i64 = u8::MAX.into();
1950         RangedI64ValueParser::new().range(start..=end)
1951     }
1952 }
1953 impl ValueParserFactory for i8 {
1954     type Parser = RangedI64ValueParser<i8>;
value_parser() -> Self::Parser1955     fn value_parser() -> Self::Parser {
1956         let start: i64 = i8::MIN.into();
1957         let end: i64 = i8::MAX.into();
1958         RangedI64ValueParser::new().range(start..=end)
1959     }
1960 }
1961 impl ValueParserFactory for u16 {
1962     type Parser = RangedI64ValueParser<u16>;
value_parser() -> Self::Parser1963     fn value_parser() -> Self::Parser {
1964         let start: i64 = u16::MIN.into();
1965         let end: i64 = u16::MAX.into();
1966         RangedI64ValueParser::new().range(start..=end)
1967     }
1968 }
1969 impl ValueParserFactory for i16 {
1970     type Parser = RangedI64ValueParser<i16>;
value_parser() -> Self::Parser1971     fn value_parser() -> Self::Parser {
1972         let start: i64 = i16::MIN.into();
1973         let end: i64 = i16::MAX.into();
1974         RangedI64ValueParser::new().range(start..=end)
1975     }
1976 }
1977 impl ValueParserFactory for u32 {
1978     type Parser = RangedI64ValueParser<u32>;
value_parser() -> Self::Parser1979     fn value_parser() -> Self::Parser {
1980         let start: i64 = u32::MIN.into();
1981         let end: i64 = u32::MAX.into();
1982         RangedI64ValueParser::new().range(start..=end)
1983     }
1984 }
1985 impl ValueParserFactory for i32 {
1986     type Parser = RangedI64ValueParser<i32>;
value_parser() -> Self::Parser1987     fn value_parser() -> Self::Parser {
1988         let start: i64 = i32::MIN.into();
1989         let end: i64 = i32::MAX.into();
1990         RangedI64ValueParser::new().range(start..=end)
1991     }
1992 }
1993 impl ValueParserFactory for i64 {
1994     type Parser = RangedI64ValueParser<i64>;
value_parser() -> Self::Parser1995     fn value_parser() -> Self::Parser {
1996         RangedI64ValueParser::new()
1997     }
1998 }
1999 impl ValueParserFactory for u64 {
2000     type Parser = RangedU64ValueParser<u64>;
value_parser() -> Self::Parser2001     fn value_parser() -> Self::Parser {
2002         RangedU64ValueParser::new()
2003     }
2004 }
2005 
2006 #[doc(hidden)]
2007 #[derive(Debug)]
2008 pub struct _AutoValueParser<T>(std::marker::PhantomData<T>);
2009 
2010 impl<T> _AutoValueParser<T> {
2011     #[doc(hidden)]
2012     #[allow(clippy::new_without_default)]
new() -> Self2013     pub fn new() -> Self {
2014         Self(Default::default())
2015     }
2016 }
2017 
2018 /// Unstable [`ValueParser`]
2019 ///
2020 /// Implementation may change to more specific instance in the future
2021 #[doc(hidden)]
2022 #[derive(Debug)]
2023 pub struct _AnonymousValueParser(ValueParser);
2024 
2025 #[doc(hidden)]
2026 pub mod via_prelude {
2027     use super::*;
2028 
2029     #[doc(hidden)]
2030     pub trait _ValueParserViaFactory: private::_ValueParserViaFactorySealed {
2031         type Parser;
value_parser(&self) -> Self::Parser2032         fn value_parser(&self) -> Self::Parser;
2033     }
2034     impl<P: ValueParserFactory> _ValueParserViaFactory for &&_AutoValueParser<P> {
2035         type Parser = P::Parser;
value_parser(&self) -> Self::Parser2036         fn value_parser(&self) -> Self::Parser {
2037             P::value_parser()
2038         }
2039     }
2040 
2041     #[doc(hidden)]
2042     pub trait _ValueParserViaValueEnum: private::_ValueParserViaValueEnumSealed {
2043         type Output;
2044 
value_parser(&self) -> Self::Output2045         fn value_parser(&self) -> Self::Output;
2046     }
2047     impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> _ValueParserViaValueEnum
2048         for &_AutoValueParser<E>
2049     {
2050         type Output = EnumValueParser<E>;
2051 
value_parser(&self) -> Self::Output2052         fn value_parser(&self) -> Self::Output {
2053             EnumValueParser::<E>::new()
2054         }
2055     }
2056 
2057     #[doc(hidden)]
2058     pub trait _ValueParserViaFromStr: private::_ValueParserViaFromStrSealed {
value_parser(&self) -> _AnonymousValueParser2059         fn value_parser(&self) -> _AnonymousValueParser;
2060     }
2061     impl<FromStr> _ValueParserViaFromStr for _AutoValueParser<FromStr>
2062     where
2063         FromStr: std::str::FromStr + std::any::Any + Clone + Send + Sync + 'static,
2064         <FromStr as std::str::FromStr>::Err:
2065             Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
2066     {
value_parser(&self) -> _AnonymousValueParser2067         fn value_parser(&self) -> _AnonymousValueParser {
2068             let func: fn(&str) -> Result<FromStr, <FromStr as std::str::FromStr>::Err> =
2069                 FromStr::from_str;
2070             _AnonymousValueParser(ValueParser::new(func))
2071         }
2072     }
2073 }
2074 
2075 /// Select a [`ValueParser`] implementation from the intended type
2076 ///
2077 /// To register a custom type with this macro, implement [`ValueParserFactory`].
2078 ///
2079 /// # Example
2080 ///
2081 /// Usage:
2082 /// ```rust
2083 /// # use std::path::PathBuf;
2084 /// # use std::path::Path;
2085 /// let mut cmd = clap::Command::new("raw")
2086 ///     .arg(
2087 ///         clap::Arg::new("output")
2088 ///             .value_parser(clap::value_parser!(PathBuf))
2089 ///             .required(true)
2090 ///     );
2091 ///
2092 /// let m = cmd.try_get_matches_from_mut(["cmd", "file.txt"]).unwrap();
2093 /// let port: &PathBuf = m.get_one("output")
2094 ///     .expect("required");
2095 /// assert_eq!(port, Path::new("file.txt"));
2096 /// ```
2097 ///
2098 /// Supported types:
2099 /// ```rust
2100 /// // Built-in types
2101 /// let parser = clap::value_parser!(String);
2102 /// assert_eq!(format!("{:?}", parser), "ValueParser::string");
2103 /// let parser = clap::value_parser!(std::ffi::OsString);
2104 /// assert_eq!(format!("{:?}", parser), "ValueParser::os_string");
2105 /// let parser = clap::value_parser!(std::path::PathBuf);
2106 /// assert_eq!(format!("{:?}", parser), "ValueParser::path_buf");
2107 /// let parser = clap::value_parser!(u16).range(3000..);
2108 /// assert_eq!(format!("{:?}", parser), "RangedI64ValueParser { bounds: (Included(3000), Included(65535)), target: PhantomData }");
2109 /// let parser = clap::value_parser!(u64).range(3000..);
2110 /// assert_eq!(format!("{:?}", parser), "RangedU64ValueParser { bounds: (Included(3000), Unbounded), target: PhantomData }");
2111 ///
2112 /// // FromStr types
2113 /// let parser = clap::value_parser!(usize);
2114 /// assert_eq!(format!("{:?}", parser), "_AnonymousValueParser(ValueParser::other(usize))");
2115 ///
2116 /// // ValueEnum types
2117 /// #[derive(Copy, Clone, Debug, PartialEq, Eq)]
2118 /// enum ColorChoice {
2119 ///     Always,
2120 ///     Auto,
2121 ///     Never,
2122 /// }
2123 /// impl clap::ValueEnum for ColorChoice {
2124 ///     // ...
2125 /// #     fn value_variants<'a>() -> &'a [Self] {
2126 /// #         &[Self::Always, Self::Auto, Self::Never]
2127 /// #     }
2128 /// #     fn to_possible_value<'a>(&self) -> Option<clap::PossibleValue<'a>> {
2129 /// #         match self {
2130 /// #             Self::Always => Some(clap::PossibleValue::new("always")),
2131 /// #             Self::Auto => Some(clap::PossibleValue::new("auto")),
2132 /// #             Self::Never => Some(clap::PossibleValue::new("never")),
2133 /// #         }
2134 /// #     }
2135 /// }
2136 /// let parser = clap::value_parser!(ColorChoice);
2137 /// assert_eq!(format!("{:?}", parser), "EnumValueParser(PhantomData)");
2138 /// ```
2139 #[macro_export]
2140 macro_rules! value_parser {
2141     ($name:ty) => {{
2142         use $crate::builder::via_prelude::*;
2143         let auto = $crate::builder::_AutoValueParser::<$name>::new();
2144         (&&&auto).value_parser()
2145     }};
2146 }
2147 
2148 mod private {
2149     use super::*;
2150 
2151     pub trait _ValueParserViaSelfSealed {}
2152     impl<P: Into<ValueParser>> _ValueParserViaSelfSealed for &&&_AutoValueParser<P> {}
2153 
2154     pub trait _ValueParserViaFactorySealed {}
2155     impl<P: ValueParserFactory> _ValueParserViaFactorySealed for &&_AutoValueParser<P> {}
2156 
2157     pub trait _ValueParserViaValueEnumSealed {}
2158     impl<E: crate::ValueEnum> _ValueParserViaValueEnumSealed for &_AutoValueParser<E> {}
2159 
2160     pub trait _ValueParserViaFromStrSealed {}
2161     impl<FromStr> _ValueParserViaFromStrSealed for _AutoValueParser<FromStr>
2162     where
2163         FromStr: std::str::FromStr + std::any::Any + Send + Sync + 'static,
2164         <FromStr as std::str::FromStr>::Err:
2165             Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
2166     {
2167     }
2168 }
2169 
2170 #[cfg(test)]
2171 mod test {
2172     use super::*;
2173 
2174     #[test]
ensure_typed_applies_to_parse()2175     fn ensure_typed_applies_to_parse() {
2176         fn parse(_: &str) -> Result<usize, std::io::Error> {
2177             Ok(10)
2178         }
2179         let cmd = crate::Command::new("cmd");
2180         let arg = None;
2181         assert_eq!(
2182             TypedValueParser::parse_ref(&parse, &cmd, arg, std::ffi::OsStr::new("foo")).unwrap(),
2183             10
2184         );
2185     }
2186 }
2187