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