mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 07:04:39 +00:00
Add ArgumentParser::at to retrieve arguments and subparsers
This allows updating attached object properties without holding external references to the various Argument and ArgumentParser objects. Closes #227 Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
This commit is contained in:
parent
6992b3b0df
commit
5f22faa973
14
README.md
14
README.md
@ -827,6 +827,20 @@ When a help message is requested from a subparser, only the help for that partic
|
||||
|
||||
Additionally, every parser has the `.is_subcommand_used("<command_name>")` and `.is_subcommand_used(subparser)` member functions to check if a subcommand was used.
|
||||
|
||||
### Getting Argument and Subparser Instances
|
||||
|
||||
```Argument``` and ```ArgumentParser``` instances added to an ```ArgumentParser``` can be retrieved with ```.at<T>()```. The default return type is ```Argument```.
|
||||
|
||||
```cpp
|
||||
argparse::ArgumentParser program("test");
|
||||
|
||||
program.add_argument("--dir");
|
||||
program.at("--dir").default_value(std::string("/home/user"));
|
||||
|
||||
program.add_subparser(argparse::ArgumentParser{"walk"});
|
||||
program.at<argparse::ArgumentParser>("walk").add_argument("depth");
|
||||
```
|
||||
|
||||
### Parse Known Args
|
||||
|
||||
Sometimes a program may only parse a few of the command-line arguments, passing the remaining arguments on to another script or program. In these cases, the `parse_known_args()` function can be useful. It works much like `parse_args()` except that it does not produce an error when extra arguments are present. Instead, it returns a list of remaining argument strings.
|
||||
|
@ -1167,6 +1167,22 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Getter for arguments and subparsers.
|
||||
* @throws std::logic_error in case of an invalid argument or subparser name
|
||||
*/
|
||||
template <typename T = Argument>
|
||||
T& at(std::string_view name) {
|
||||
if constexpr (std::is_same_v<T, Argument>) {
|
||||
return (*this)[name];
|
||||
} else {
|
||||
auto subparser_it = m_subparser_map.find(name);
|
||||
if (subparser_it != m_subparser_map.end()) {
|
||||
return subparser_it->second->get();
|
||||
}
|
||||
throw std::logic_error("No such subparser: " + std::string(name));
|
||||
}
|
||||
}
|
||||
|
||||
ArgumentParser &set_prefix_chars(std::string prefix_chars) {
|
||||
m_prefix_chars = std::move(prefix_chars);
|
||||
return *this;
|
||||
|
@ -27,6 +27,7 @@ file(GLOB ARGPARSE_TEST_SOURCES
|
||||
main.cpp
|
||||
test_actions.cpp
|
||||
test_append.cpp
|
||||
test_as_container.cpp
|
||||
test_bool_operator.cpp
|
||||
test_compound_arguments.cpp
|
||||
test_container_arguments.cpp
|
||||
|
52
test/test_as_container.cpp
Normal file
52
test/test_as_container.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include <argparse/argparse.hpp>
|
||||
#include <doctest.hpp>
|
||||
|
||||
using doctest::test_suite;
|
||||
|
||||
TEST_CASE("Get argument with .at()" * test_suite("as_container")) {
|
||||
argparse::ArgumentParser program("test");
|
||||
auto &dir_arg = program.add_argument("--dir");
|
||||
program.at("--dir").default_value(std::string("/home/user"));
|
||||
|
||||
SUBCASE("and default value") {
|
||||
program.parse_args({"test"});
|
||||
REQUIRE(&(program.at("--dir")) == &dir_arg);
|
||||
REQUIRE(program["--dir"] == std::string("/home/user"));
|
||||
REQUIRE(program.at("--dir") == std::string("/home/user"));
|
||||
}
|
||||
|
||||
SUBCASE("and user-supplied value") {
|
||||
program.parse_args({"test", "--dir", "/usr/local/database"});
|
||||
REQUIRE(&(program.at("--dir")) == &dir_arg);
|
||||
REQUIRE(program["--dir"] == std::string("/usr/local/database"));
|
||||
REQUIRE(program.at("--dir") == std::string("/usr/local/database"));
|
||||
}
|
||||
|
||||
SUBCASE("with unknown argument") {
|
||||
program.parse_args({"test"});
|
||||
REQUIRE_THROWS_WITH_AS(program.at("--folder"),
|
||||
"No such argument: --folder", std::logic_error);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Get subparser with .at()" * test_suite("as_container")) {
|
||||
argparse::ArgumentParser program("test");
|
||||
|
||||
argparse::ArgumentParser walk_cmd("walk");
|
||||
auto &speed = walk_cmd.add_argument("speed");
|
||||
|
||||
program.add_subparser(walk_cmd);
|
||||
|
||||
SUBCASE("and its argument") {
|
||||
program.parse_args({"test", "walk", "4km/h"});
|
||||
REQUIRE(&(program.at<argparse::ArgumentParser>("walk")) == &walk_cmd);
|
||||
REQUIRE(&(program.at<argparse::ArgumentParser>("walk").at("speed")) == &speed);
|
||||
REQUIRE(program.at<argparse::ArgumentParser>("walk").is_used("speed"));
|
||||
}
|
||||
|
||||
SUBCASE("with unknown command") {
|
||||
program.parse_args({"test"});
|
||||
REQUIRE_THROWS_WITH_AS(program.at<argparse::ArgumentParser>("fly"),
|
||||
"No such subparser: fly", std::logic_error);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user