pub trait TypedValueParser: Clone + Send + Sync + 'static {
    type Value: Send + Sync + Clone;

    fn parse_ref(
        &self,
        cmd: &Command,
        arg: Option<&Arg>,
        value: &OsStr
    ) -> Result<Self::Value, Error>; fn parse(
        &self,
        cmd: &Command,
        arg: Option<&Arg>,
        value: OsString
    ) -> Result<Self::Value, Error> { ... } fn possible_values(
        &self
    ) -> Option<Box<dyn Iterator<Item = PossibleValue> + '_>> { ... } fn map<T, F>(self, func: F) -> MapValueParser<Self, F>
    where
        T: Send + Sync + Clone,
        F: Fn(Self::Value) -> T + Clone
, { ... } fn 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 Error + Send + Sync + 'static>>
, { ... } }
Expand description

Parse/validate argument values

As alternatives to implementing TypedValueParser,

See ValueParserFactory to register TypedValueParser::Value with value_parser!.

Example

#[derive(Clone)]
struct Custom(u32);

#[derive(Clone)]
struct CustomValueParser;

impl clap::builder::TypedValueParser for CustomValueParser {
   type Value = Custom;

   fn parse_ref(
       &self,
       cmd: &clap::Command,
       arg: Option<&clap::Arg>,
       value: &std::ffi::OsStr,
   ) -> Result<Self::Value, clap::Error> {
       let inner = clap::value_parser!(u32);
       let val = inner.parse_ref(cmd, arg, value)?;

       const INVALID_VALUE: u32 = 10;
       if val == INVALID_VALUE {
           let mut err = clap::Error::new(ErrorKind::ValueValidation)
               .with_cmd(cmd);
           if let Some(arg) = arg {
               err.insert(ContextKind::InvalidArg, ContextValue::String(arg.to_string()));
           }
           err.insert(ContextKind::InvalidValue, ContextValue::String(INVALID_VALUE.to_string()));
           return Err(err);
       }

       Ok(Custom(val))
   }
}

Required Associated Types§

Argument’s value type

Required Methods§

Parse the argument value

When arg is None, an external subcommand value is being parsed.

Provided Methods§

Parse the argument value

When arg is None, an external subcommand value is being parsed.

Reflect on enumerated value properties

Error checking should not be done with this; it is mostly targeted at user-facing applications like errors and completion.

Adapt a TypedValueParser from one value to another

Example
let cmd = Command::new("mycmd")
    .arg(
        Arg::new("flag")
            .long("flag")
            .action(clap::ArgAction::SetTrue)
            .value_parser(
                BoolishValueParser::new()
                .map(|b| -> usize {
                    if b { 10 } else { 5 }
                })
            )
    );

let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
assert!(matches.contains_id("flag"));
assert_eq!(
    matches.get_one::<usize>("flag").copied(),
    Some(10)
);

let matches = cmd.try_get_matches_from(["mycmd"]).unwrap();
assert!(matches.contains_id("flag"));
assert_eq!(
    matches.get_one::<usize>("flag").copied(),
    Some(5)
);

Adapt a TypedValueParser from one value to another

Example
let cmd = Command::new("mycmd")
    .arg(
        Arg::new("flag")
            .long("flag")
            .value_parser(
                OsStringValueParser::new()
                .try_map(verify_ext)
            )
    );

fn verify_ext(os: OsString) -> Result<PathBuf, &'static str> {
    let path = PathBuf::from(os);
    if path.extension() != Some(OsStr::new("rs")) {
        return Err("only Rust files are supported");
    }
    Ok(path)
}

let error = cmd.clone().try_get_matches_from(["mycmd", "--flag", "foo.txt"]).unwrap_err();
error.print();

let matches = cmd.try_get_matches_from(["mycmd", "--flag", "foo.rs"]).unwrap();
assert!(matches.contains_id("flag"));
assert_eq!(
    matches.get_one::<PathBuf>("flag").map(|s| s.as_path()),
    Some(Path::new("foo.rs"))
);

Implementors§