From fbaf3e46d5981a3f109c1bc0fcf2c0ca6e20af2c Mon Sep 17 00:00:00 2001 From: Lydia Buntrock Date: Tue, 15 Feb 2022 11:52:05 +0100 Subject: [PATCH] [DOC] Copy over the cookbook entry about the custom validator (#62) * [DOC] Copy over the cookbook entry about "how to build your own validator" Signed-off-by: Lydia Buntrock * Apply suggestions from code review Co-authored-by: Enrico Seiler --- doc/cookbook/index.md | 6 +++ doc/tutorial/argument_parser/index.md | 6 +-- .../concepts/custom_validator_solution.cpp | 54 +++++++++++++++++++ .../concepts/custom_validator_solution.out | 3 ++ 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 doc/tutorial/concepts/custom_validator_solution.cpp create mode 100644 doc/tutorial/concepts/custom_validator_solution.out diff --git a/doc/cookbook/index.md b/doc/cookbook/index.md index e8f78695..06dcb18a 100644 --- a/doc/cookbook/index.md +++ b/doc/cookbook/index.md @@ -17,3 +17,9 @@ please feel free to contact us. # Constructing a subcommand argument parser \include doc/howto/subcommand_argument_parser/subcommand_arg_parse.cpp + +# Write a custom validator {#cookbook_custom_validator} +This recipe implements a validator that checks whether a numeric argument is an integral square (i.e. 0, 1, 4, 9...). +Invalid values throw a sharg::validation_error. + +\snippet doc/tutorial/concepts/custom_validator_solution.cpp validator diff --git a/doc/tutorial/argument_parser/index.md b/doc/tutorial/argument_parser/index.md index 3c3e0bae..1da95b23 100644 --- a/doc/tutorial/argument_parser/index.md +++ b/doc/tutorial/argument_parser/index.md @@ -418,7 +418,7 @@ input when parsing the command line. The sharg::argument_parser provides **valid A *validator* is a [functor](https://stackoverflow.com/questions/356950/what-are-c-functors-and-their-uses) that is called within the argument parser after retrieving and converting a command line argument. We provide several validators, which we hope cover most of the use cases, but you can always create your own validator -(see section [Create your own validator](#section_create_your_own_validator)). +(see section [Create your own validator](#cookbook_custom_validator)). \attention You can pass a validator to the sharg::argument_parser::add_option function only after passing the sharg::option_spec parameter. Pass the sharg::option_spec::standard tag if there are no further restrictions on your option. @@ -432,8 +432,8 @@ The following validators are provided in the SeqAn library and can be included w All the validators below work on single values or a container of values. In case the variable is a container, the validator is called **on each element** separately. -\note If the validators below do not suit your needs, you can always create your own validator. See the concept tutorial -for an example of how to create your own validator. +\note If the validators below do not suit your needs, you can always create your own validator +(see section [Create your own validator](#cookbook_custom_validator)). ### The sharg::arithmetic_range_validator diff --git a/doc/tutorial/concepts/custom_validator_solution.cpp b/doc/tutorial/concepts/custom_validator_solution.cpp new file mode 100644 index 00000000..d7119f05 --- /dev/null +++ b/doc/tutorial/concepts/custom_validator_solution.cpp @@ -0,0 +1,54 @@ +#include +//![validator] +#include + +struct custom_validator +{ + using option_value_type = double; // used for all arithmetic types + + void operator() (option_value_type const & val) const + { + if ((std::round(val) != val) || // not an integer + (std::pow(std::round(std::sqrt(val)), 2) != val)) // not a square + { + throw sharg::validation_error{"The provided number is not an arithmetic square."}; + } + } + + std::string get_help_page_message () const + { + return "Value must be the square of an integral number."; + } +}; +//![validator] + +static_assert(sharg::validator); + +//![main] +int main(int argc, char ** argv) +{ + sharg::argument_parser myparser("Test-Parser", argc, argv); + + int32_t variable{}; + int16_t variable2{}; + + myparser.add_option(variable, 'i', "", "An int that is a square", sharg::option_spec::standard, + custom_validator{}); // ← your validator is used! + + myparser.add_option(variable2, 'j', "", "An int that is a square and within [0,20].", sharg::option_spec::standard, + custom_validator{} | sharg::arithmetic_range_validator{0, 20}); // ← now it's chained + + try + { + myparser.parse(); // trigger command line parsing + } + catch (sharg::argument_parser_error const & ext) + { + std::cout << ext.what() << '\n'; + return -1; + } + std::cout << "Yeah!\n"; + + return 0; +} +//![main] diff --git a/doc/tutorial/concepts/custom_validator_solution.out b/doc/tutorial/concepts/custom_validator_solution.out new file mode 100644 index 00000000..77692439 --- /dev/null +++ b/doc/tutorial/concepts/custom_validator_solution.out @@ -0,0 +1,3 @@ +Test-Parser +=========== + Try -h or --help for more information.