diff options
| author | Lexi Winter <lexi@le-fay.org> | 2025-06-28 19:25:55 +0100 |
|---|---|---|
| committer | Lexi Winter <lexi@le-fay.org> | 2025-06-28 19:25:55 +0100 |
| commit | a2d7181700ac64b8e7a4472ec26dfa253b38f188 (patch) | |
| tree | 23c5a9c8ec4089ac346e2e0f9391909c3089b66b /nihil.cli/command_map.ccm | |
| parent | f226d46ee02b57dd76a4793593aa8d66e1c58353 (diff) | |
| download | nihil-a2d7181700ac64b8e7a4472ec26dfa253b38f188.tar.gz nihil-a2d7181700ac64b8e7a4472ec26dfa253b38f188.tar.bz2 | |
split nihil into separate modules
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 |
