From 0996557a530692d276fd247995523344bfae084a Mon Sep 17 00:00:00 2001 From: Pavel Belikov Date: Sat, 18 Nov 2017 15:54:08 +0300 Subject: add ActionFlag --- args.hxx | 36 ++++++++++++++++++++++++++++++++++++ test.cxx | 19 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/args.hxx b/args.hxx index 7af24c4..7a4ccf7 100644 --- a/args.hxx +++ b/args.hxx @@ -2577,6 +2577,42 @@ namespace args } }; + /** A flag class that calls a function when it's matched + */ + class ActionFlag : public FlagBase + { + private: + std::function &)> action; + Nargs nargs; + + public: + ActionFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Nargs nargs_, std::function &)> action_, Options options_ = {}): + FlagBase(name_, help_, std::move(matcher_), options_), action(std::move(action_)), nargs(nargs_) + { + group_.Add(*this); + } + + ActionFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, std::function action_, Options options_ = {}): + FlagBase(name_, help_, std::move(matcher_), options_), nargs(1) + { + group_.Add(*this); + action = [action_](const std::vector &a) { return action_(a.at(0)); }; + } + + ActionFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, std::function action_, Options options_ = {}): + FlagBase(name_, help_, std::move(matcher_), options_), nargs(0) + { + group_.Add(*this); + action = [action_](const std::vector &) { return action_(); }; + } + + virtual Nargs NumberOfArguments() const noexcept override + { return nargs; } + + virtual void ParseValue(const std::vector &value) override + { action(value); } + }; + /** A default Reader class for argument classes * * Simply uses a std::istringstream to read into the destination type, and diff --git a/test.cxx b/test.cxx index 1189f97..5f97c87 100644 --- a/test.cxx +++ b/test.cxx @@ -1066,6 +1066,25 @@ TEST_CASE("HelpParams work as expected", "[args]") } +TEST_CASE("ActionFlag works as expected", "[args]") +{ + args::ArgumentParser p("parser"); + std::string s; + + args::ActionFlag action0(p, "name", "description", {'x'}, [&]() { s = "flag"; }); + args::ActionFlag action1(p, "name", "description", {'y'}, [&](const std::string &arg) { s = arg; }); + args::ActionFlag actionN(p, "name", "description", {'z'}, 2, [&](const std::vector &arg) { s = arg[0] + arg[1]; }); + + p.ParseArgs(std::vector{"-x"}); + REQUIRE(s == "flag"); + + p.ParseArgs(std::vector{"-y", "a"}); + REQUIRE(s == "a"); + + p.ParseArgs(std::vector{"-z", "a", "b"}); + REQUIRE(s == "ab"); +} + #undef ARGS_HXX #define ARGS_TESTNAMESPACE #define ARGS_NOEXCEPT -- cgit v1.2.1 From ec3c42cdd95eba66d374994c7153e954c05b8f06 Mon Sep 17 00:00:00 2001 From: Pavel Belikov Date: Sat, 18 Nov 2017 15:57:51 +0300 Subject: add test for throwing exception from ActionFlag --- test.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test.cxx b/test.cxx index 5f97c87..44cde49 100644 --- a/test.cxx +++ b/test.cxx @@ -1074,6 +1074,7 @@ TEST_CASE("ActionFlag works as expected", "[args]") args::ActionFlag action0(p, "name", "description", {'x'}, [&]() { s = "flag"; }); args::ActionFlag action1(p, "name", "description", {'y'}, [&](const std::string &arg) { s = arg; }); args::ActionFlag actionN(p, "name", "description", {'z'}, 2, [&](const std::vector &arg) { s = arg[0] + arg[1]; }); + args::ActionFlag actionThrow(p, "name", "description", {'v'}, [&]() { throw std::runtime_error(""); }); p.ParseArgs(std::vector{"-x"}); REQUIRE(s == "flag"); @@ -1083,6 +1084,8 @@ TEST_CASE("ActionFlag works as expected", "[args]") p.ParseArgs(std::vector{"-z", "a", "b"}); REQUIRE(s == "ab"); + + REQUIRE_THROWS_AS(p.ParseArgs(std::vector{"-v"}), std::runtime_error); } #undef ARGS_HXX -- cgit v1.2.1