22#include <unordered_map>
26namespace cli::commands
37 : std::runtime_error(buildMessage(missingId, chain)), missing(missingId), path(chain)
41 const std::string &missingId() const noexcept {
return missing; }
43 const std::vector<std::string> &insertChain() const noexcept {
return path; }
47 std::vector<std::string> path;
49 static std::string buildMessage(
const std::string &
id,
const std::vector<std::string> &chain);
67 template <
typename... Ids>
68 void insert(std::unique_ptr<Command> cmd, std::string_view parentId, Ids &&...rest)
70 Command *parentCommandPtr =
find(parentId, std::forward<Ids>(rest)...);
71 if (!parentCommandPtr)
73 std::vector<std::string> chain{std::string(parentId), std::string(rest)...};
82 void insert(std::unique_ptr<Command> cmd)
84 root->withSubCommand(std::move(cmd));
93 return findRecursive(root.get(), std::forward<Ids>(ids)...);
103 forEachCommandRecursive(root.get(), func);
114 forEachCommandRecursive(root.get(), func);
149 std::unique_ptr<Command> root;
150 std::unordered_map<Command *, std::string> commandPathMap;
152 void buildCommandPathMapRecursive(
Command *cmd, std::vector<std::string> &path,
153 const std::string &separator);
156 template <
typename... Ids>
157 static Command *findRecursive(
Command *cmdPtr, std::string_view
id, Ids &&...rest)
163 Command *subCommandPtr = it->second.get();
165 if constexpr (
sizeof...(rest) == 0)
168 return subCommandPtr;
171 return findRecursive(subCommandPtr, std::forward<Ids>(rest)...);
174 static Command *findRecursive(Command *cmdPtr) {
return cmdPtr; }
177 static void forEachCommandRecursive(Command *cmdPtr,
const std::function<
void(Command *)> &func)
182 for (
const auto &[key, subCommandPtr] : cmdPtr->getSubCommands())
184 forEachCommandRecursive(subCommandPtr.get(), func);
189 static void forEachCommandRecursive(Command *cmdPtr,
const std::function<
void(Command &)> &func)
194 for (
const auto &[key, subCommandPtr] : cmdPtr->getSubCommands())
196 forEachCommandRecursive(subCommandPtr.get(), func);
202 static void getAllCommandsRecursive(Command *cmdPtr, std::vector<Command *> &commands)
206 commands.push_back(cmdPtr);
207 for (
const auto &[key, subCommandPtr] : cmdPtr->getSubCommands())
209 getAllCommandsRecursive(subCommandPtr.get(), commands);
215 static void getAllCommandsRecursive(
const Command *cmdPtr, std::vector<const Command *> &commands)
219 commands.push_back(cmdPtr);
220 for (
const auto &[key, subCommandPtr] : cmdPtr->getSubCommands())
222 getAllCommandsRecursive(subCommandPtr.get(), commands);
Exception thrown when a command is not found in the command tree.
Definition command_tree.h:31
CommandNotFoundException(const std::string &missingId, const std::vector< std::string > &chain)
Construct a new CommandNotFoundException.
Definition command_tree.h:36
Tree structure to manage commands and their subcommands.
Definition command_tree.h:56
void forEachCommand(const std::function< void(Command &)> &func) const
Apply a function to each command in the tree.
Definition command_tree.h:110
void insert(std::unique_ptr< Command > cmd, std::string_view parentId, Ids &&...rest)
Insert a command into the tree.
Definition command_tree.h:68
void buildCommandPathMap(const std::string &separator=" ")
Build a map of command paths for quick lookup.
Definition command_tree.cpp:33
std::string_view getPathForCommand(Command *cmd) const
Get the path for a command in the tree.
Definition command_tree.cpp:28
const Command * getRootCommand() const
Get the root command of the tree.
Definition command_tree.h:124
void forEachCommand(const std::function< void(Command *)> &func) const
Apply a function to each command in the tree.
Definition command_tree.h:99
Command * getRootCommand()
Get the root command of the tree.
Definition command_tree.h:120
std::vector< const Command * > getAllCommandsConst() const
Get a vector of all commands in the tree (const version).
Definition command_tree.cpp:93
void insert(std::unique_ptr< Command > cmd)
Insert a command into the tree.
Definition command_tree.h:82
std::vector< Command * > getAllCommands() const
Get a vector of all commands in the tree.
Definition command_tree.cpp:83
Command * find(Ids &&...ids) const
Find a command in the tree by a path of identifiers leading to it.
Definition command_tree.h:91
Represents a command in the CLI application.
Definition command.h:36
Command & withSubCommand(std::unique_ptr< Command > subCommandPtr)
Add a sub-command to this command.
Definition command.cpp:104
auto & getSubCommands()
Get all sub-commands of the command.
Definition command.h:170