Trait clap_builder::builder::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(
&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
,
- Use
Fn(&str) -> Result<T, E>
which implementsTypedValueParser
TypedValueParser::map
orTypedValueParser::try_map
to adapt an existingTypedValueParser
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§
Required Methods§
Provided Methods§
sourcefn parse(
&self,
cmd: &Command,
arg: Option<&Arg>,
value: OsString
) -> Result<Self::Value, Error>
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.
sourcefn possible_values(
&self
) -> Option<Box<dyn Iterator<Item = PossibleValue> + '_>>
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.
sourcefn map<T, F>(self, func: F) -> MapValueParser<Self, F>where
T: Send + Sync + Clone,
F: Fn(Self::Value) -> T + Clone,
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)
);
sourcefn 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>>,
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>>,
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"))
);