You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to be able to validate arbitrary invariants (ex a+b<100) on this struct after it has been fully validated and before returning from parse.
I see in the docs here that you can already perform arbitrary validation after the Parse() call. However, it seems ugly that you have to include this extra parsing logic in the actual program code instead of defining it on the struct itself.
Its also problematic when integrating the cli with klask. The program runs through to here and should return an error but currently will continue until the user's main and then finally report the invalid args.
Describe the solution you'd like
Some way of specifying a value parser fn(self)->Self that runs on the entire parsed struct before leaving clap's own validation logic. So from_arg_matches_mut, try_get_matches_from_mut and the like use this to validate after parsing the whole struct.
Whatever syntax is used for this it should also work for #[derive(Args)] so subcommands can also handle their own validated invariants.
For example the following syntax could be created so the following program never panics in the actual user's main. Instead clap should use the value_parser=Self::post_validate:
use clap::Parser;constMAX_VALUE:usize = 100;#[derive(Clone,Debug,Parser(value_parser=Self::post_validate))]structCli{a:usize,b:usize,c:usize,}implCli{fnpost_validate(self) -> Result<Self,String>{ifself.a + self.b > MAX_VALUE{Err(format!("a and b should not add up to more than {MAX_VALUE}"))}else{Ok(self)}}}fnmain(){let opt = Cli::parse();assert!(
opt.a + opt.b <= MAX_VALUE,
"Clap didn't validate all invariants");dbg!(opt);}
Alternatives, if applicable
Its not preferred but acceptable if the function must be free and not an associated to the struct.
Currently I can only think of accomplishing post parse validation by:
use clap::{CommandFactory,Parser};constMAX_VALUE:usize = 100;#[derive(Clone,Debug,Parser/* (value_parser=Self::post_validate) */)]structCli{a:usize,b:usize,c:usize,}implCli{fnpost_validate(self) -> Result<Self,String>{ifself.a + self.b > MAX_VALUE{Err(format!("a and b should not add up to more than {MAX_VALUE}"))}else{Ok(self)}}}fnhandler(error:String) -> ! {letmut cmd = Cli::command();
cmd.error(clap::error::ErrorKind::ArgumentConflict, error).exit()}fnmain(){let opt = Cli::parse().post_validate().map_err(handler).unwrap();assert!(
opt.a + opt.b <= MAX_VALUE,
"Clap didn't validate all invariants");dbg!(opt);}
Additional Context
The klask link may show that it only supports clap v3 but several forks that support v4 exist (1, 2)
The text was updated successfully, but these errors were encountered:
So is there a better currently supported way of doing this or should I stick to let opt = Cli::parse().post_validate().map_err(handler).unwrap(); until #3008 issue is resolved?
Please complete the following tasks
Clap Version
clap = "4.3.8"
Describe your use case
TLDR: Post process validation function that runs with clap's own parsing to support arbitrary invariant validation.
I have a struct with complex multi-field properties and invariants that should be upheld when finished parsing. An example might looks like:
I would like to be able to validate arbitrary invariants (ex
a+b<100
) on this struct after it has been fully validated and before returning from parse.I see in the docs here that you can already perform arbitrary validation after the
Parse()
call. However, it seems ugly that you have to include this extra parsing logic in the actual program code instead of defining it on the struct itself.Its also problematic when integrating the cli with klask. The program runs through to here and should return an error but currently will continue until the user's main and then finally report the invalid args.
Describe the solution you'd like
Some way of specifying a value parser
fn(self)->Self
that runs on the entire parsed struct before leaving clap's own validation logic. Sofrom_arg_matches_mut
,try_get_matches_from_mut
and the like use this to validate after parsing the whole struct.Whatever syntax is used for this it should also work for
#[derive(Args)]
sosubcommand
s can also handle their own validated invariants.For example the following syntax could be created so the following program never panics in the actual user's main. Instead clap should use the
value_parser
=Self::post_validate
:Alternatives, if applicable
Additional Context
The klask link may show that it only supports clap v3 but several forks that support v4 exist (1, 2)
The text was updated successfully, but these errors were encountered: