Skip to main content

## TypedValueParser

# Trait TypedValueParser

Source

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

        // Required method
        fn parse_ref(
            &self,
            cmd: &Command,
            arg: Option<&Arg>,
            value: &OsStr,
        ) -> Result<Self::Value, Error>;

        // Provided methods
        fn parse_ref_(
            &self,
            cmd: &Command,
            arg: Option<&Arg>,
            value: &OsStr,
            _source: ValueSource,
        ) -> Result<Self::Value, Error> { ... }
        fn parse(
            &self,
            cmd: &Command,
            arg: Option<&Arg>,
            value: OsString,
        ) -> Result<Self::Value, Error> { ... }
        fn parse_(
            &self,
            cmd: &Command,
            arg: Option<&Arg>,
            value: OsString,
            _source: ValueSource,
        ) -> 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 + Sync + Send>> { ... }
    }

Expand description

Parse/validate argument values

As alternatives to implementing `TypedValueParser`,

- Use `Fn(&str) -> Result<T, E>` which implements `TypedValueParser`
- `TypedValueParser::map` or `TypedValueParser::try_map` to adapt an existing `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§

Source

#### type Value: Send + Sync + Clone

Argument’s value type

## Required Methods§

Source

#### fn parse_ref( &self, cmd: &Command, arg: Option<&Arg>, value: &OsStr, ) -> Result<Self::Value, Error>

Parse the argument value

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

## Provided Methods§

Source

#### fn parse_ref_( &self, cmd: &Command, arg: Option<&Arg>, value: &OsStr, _source: ValueSource, ) -> Result<Self::Value, Error>

Parse the argument value

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

Source

#### fn parse( &self, cmd: &Command, arg: Option<&Arg>, value: OsString, ) -> Result<Self::Value, Error>

Parse the argument value

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

Source

#### fn parse_( &self, cmd: &Command, arg: Option<&Arg>, value: OsString, _source: ValueSource, ) -> Result<Self::Value, Error>

Parse the argument value

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

Source

#### fn possible_values( &self, ) -> Option<Box<dyn Iterator<Item = PossibleValue> + '_>>

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.

##### Examples found in repository?

examples/typed-derive/custom.rs (line 76)

    71    fn possible_values(
    72        &self,
    73    ) -> Option<Box<dyn Iterator<Item = clap::builder::PossibleValue> + '_>> {
    74        let inner_parser = clap::builder::EnumValueParser::<BumpLevel>::new();
    75        #[allow(clippy::needless_collect)] // Erasing a lifetime
    76        inner_parser.possible_values().map(|ps| {
    77            let ps = ps.collect::<Vec<_>>();
    78            let ps: Box<dyn Iterator<Item = clap::builder::PossibleValue> + '_> =
    79                Box::new(ps.into_iter());
    80            ps
    81        })
    82    }

Source

#### fn map<T, F>(self, func: F) -> MapValueParser<Self, F>
where T: Send + Sync + Clone, F: Fn(Self::Value) -> T + Clone,

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)
    );

Source

#### 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 + Sync + Send>>,

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"))
    );

## Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

## Implementors§

Source§

### impl TypedValueParser for BoolValueParser

Source§

#### type Value = bool

Source§

### impl TypedValueParser for BoolishValueParser

Source§

#### type Value = bool

Source§

### impl TypedValueParser for FalseyValueParser

Source§

#### type Value = bool

Source§

### impl TypedValueParser for NonEmptyStringValueParser

Source§

#### type Value = String

Source§

### impl TypedValueParser for OsStringValueParser

Source§

#### type Value = OsString

Source§

### impl TypedValueParser for PathBufValueParser

Source§

#### type Value = PathBuf

Source§

### impl TypedValueParser for PossibleValuesParser

Source§

#### type Value = String

Source§

### impl TypedValueParser for StringValueParser

Source§

#### type Value = String

Source§

### impl TypedValueParser for UnknownArgumentValueParser

Source§

#### type Value = String

Source§

### impl<E> TypedValueParser for EnumValueParser<E>
where E: ValueEnum + Clone + Send + Sync + 'static,

Source§

#### type Value = E

Source§

### impl<F, T, E> TypedValueParser for F
where F: Fn(&str) -> Result<T, E> + Clone + Send + Sync + 'static, E: Into<Box<dyn Error + Sync + Send>>, T: Send + Sync + Clone,

Source§

#### type Value = T

Source§

### impl<P, F, T, E> TypedValueParser for TryMapValueParser<P, F>
where P: TypedValueParser, <P as TypedValueParser>::Value: Send + Sync + Clone, F: Fn(<P as TypedValueParser>::Value) -> Result<T, E> + Clone + Send + Sync + 'static, T: Send + Sync + Clone, E: Into<Box<dyn Error + Sync + Send>>,

Source§

#### type Value = T

Source§

### impl<P, F, T> TypedValueParser for MapValueParser<P, F>
where P: TypedValueParser, <P as TypedValueParser>::Value: Send + Sync + Clone, F: Fn(<P as TypedValueParser>::Value) -> T + Clone + Send + Sync + 'static, T: Send + Sync + Clone,

Source§

#### type Value = T

Source§

### impl<T> TypedValueParser for RangedI64ValueParser<T>
where T: TryFrom<i64> + Clone + Send + Sync + 'static, <T as TryFrom<i64>>::Error: Send + Sync + 'static + Error + ToString,

Source§

#### type Value = T

Source§

### impl<T> TypedValueParser for RangedU64ValueParser<T>
where T: TryFrom<u64> + Clone + Send + Sync + 'static, <T as TryFrom<u64>>::Error: Send + Sync + 'static + Error + ToString,

Source§

#### type Value = T