diff options
Diffstat (limited to 'src/libutil/args.hh')
-rw-r--r-- | src/libutil/args.hh | 123 |
1 files changed, 66 insertions, 57 deletions
diff --git a/src/libutil/args.hh b/src/libutil/args.hh index f93459c96..250244162 100644 --- a/src/libutil/args.hh +++ b/src/libutil/args.hh @@ -28,55 +28,60 @@ protected: static const size_t ArityAny = std::numeric_limits<size_t>::max(); + struct Handler + { + std::function<void(std::vector<std::string>)> fun; + size_t arity; + + Handler() {} + + Handler(std::function<void(std::vector<std::string>)> && fun) + : fun(std::move(fun)) + , arity(ArityAny) + { } + + Handler(std::function<void()> && handler) + : fun([handler{std::move(handler)}](std::vector<std::string>) { handler(); }) + , arity(0) + { } + + Handler(std::function<void(std::string)> && handler) + : fun([handler{std::move(handler)}](std::vector<std::string> ss) { + handler(std::move(ss[0])); + }) + , arity(1) + { } + + Handler(std::function<void(std::string, std::string)> && handler) + : fun([handler{std::move(handler)}](std::vector<std::string> ss) { + handler(std::move(ss[0]), std::move(ss[1])); + }) + , arity(2) + { } + + Handler(std::vector<std::string> * dest) + : fun([=](std::vector<std::string> ss) { *dest = ss; }) + , arity(ArityAny) + { } + + template<class T> + Handler(T * dest) + : fun([=](std::vector<std::string> ss) { *dest = ss[0]; }) + , arity(1) + { } + + template<class T> + Handler(T * dest, const T & val) + : fun([=](std::vector<std::string> ss) { *dest = val; }) + , arity(0) + { } + }; + /* Flags. */ struct Flag { typedef std::shared_ptr<Flag> ptr; - struct Handler - { - std::function<void(std::vector<std::string>)> fun; - size_t arity; - - Handler() {} - - Handler(std::function<void(std::vector<std::string>)> && fun) - : fun(std::move(fun)) - , arity(ArityAny) - { } - - Handler(std::function<void()> && handler) - : fun([handler{std::move(handler)}](std::vector<std::string>) { handler(); }) - , arity(0) - { } - - Handler(std::function<void(std::string)> && handler) - : fun([handler{std::move(handler)}](std::vector<std::string> ss) { - handler(std::move(ss[0])); - }) - , arity(1) - { } - - Handler(std::function<void(std::string, std::string)> && handler) - : fun([handler{std::move(handler)}](std::vector<std::string> ss) { - handler(std::move(ss[0]), std::move(ss[1])); - }) - , arity(2) - { } - - template<class T> - Handler(T * dest) - : fun([=](std::vector<std::string> ss) { *dest = ss[0]; }) - , arity(1) - { } - - template<class T> - Handler(T * dest, const T & val) - : fun([=](std::vector<std::string> ss) { *dest = val; }) - , arity(0) - { } - }; - std::string longName; char shortName = 0; std::string description; @@ -99,9 +104,9 @@ protected: struct ExpectedArg { std::string label; - size_t arity = 0; // 0 = any bool optional = false; - std::function<void(std::vector<std::string>)> handler; + Handler handler; + std::function<void(size_t, std::string_view)> completer; }; std::list<ExpectedArg> expectedArgs; @@ -175,26 +180,30 @@ public: }); } + void expectArgs(ExpectedArg && arg) + { + expectedArgs.emplace_back(std::move(arg)); + } + /* Expect a string argument. */ void expectArg(const std::string & label, string * dest, bool optional = false) { - expectedArgs.push_back(ExpectedArg{label, 1, optional, [=](std::vector<std::string> ss) { - *dest = ss[0]; - }}); + expectArgs({ + .label = label, + .optional = true, + .handler = {dest} + }); } - void expectPathArg(const std::string & label, string * dest, bool optional = false); - /* Expect 0 or more arguments. */ void expectArgs(const std::string & label, std::vector<std::string> * dest) { - expectedArgs.push_back(ExpectedArg{label, 0, false, [=](std::vector<std::string> ss) { - *dest = std::move(ss); - }}); + expectArgs({ + .label = label, + .handler = {dest} + }); } - void expectPathArgs(const std::string & label, std::vector<std::string> * dest); - friend class MultiCommand; }; @@ -266,6 +275,6 @@ extern bool pathCompletions; std::optional<std::string> needsCompletion(std::string_view s); -void completePath(size_t, std::string_view s); +void completePath(size_t, std::string_view prefix); } |