diff options
Diffstat (limited to 'nihil.cli/command_map.ccm')
| -rw-r--r-- | nihil.cli/command_map.ccm | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/nihil.cli/command_map.ccm b/nihil.cli/command_map.ccm new file mode 100644 index 0000000..8cf9d9c --- /dev/null +++ b/nihil.cli/command_map.ccm @@ -0,0 +1,67 @@ +/* + * This source code is released into the public domain. + */ + +module; + +#include <functional> +#include <iostream> +#include <map> +#include <string> +#include <utility> + +export module nihil.cli:command_map; + +import nihil.util; +import :usage_error; + +/* + * command_map represents a hierarchical list of commands. At each level, + * a command is mapped to a handler, which can either be a function, in + * which case we execute the function, or another command_map, in which + * case we invoke the new map + */ + +namespace nihil { + +export struct command; + +/* + * Register a command; used by command<>::command(). + */ +auto register_command(std::string_view path, command *) noexcept -> void; + +/* + * A command that can be invoked. Instantiating a command adds this command + * to the global command table. If an error occurs, the program will abort. + */ +export struct command { + command(std::string_view path, std::string_view usage, auto &&fn) + : m_path(path) + , m_usage(usage) + , m_handler(std::forward<decltype(fn)>(fn)) + { + register_command(path, this); + } + + [[nodiscard]] auto path(this command const &self) -> std::string_view + { + return self.m_path; + } + + auto invoke(this command const &self, int argc, char **argv) -> int + { + return std::invoke(self.m_handler, argc, argv); + } + +private: + std::string_view m_path; + std::string_view m_usage; + std::function<int (int, char **)> m_handler; +}; + +// The public API. +export [[nodiscard]] auto dispatch_command(int argc, char **argv) -> int; +export auto print_usage(std::string_view prefix) -> void; + +} // namespace nihil |
