From da02080fc1db3be9275832b7ad929165b1a38e3e Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 25 Jan 2026 11:33:55 +0100 Subject: Move more command line parsing into a module --- cli/command_line.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'cli/command_line.cpp') diff --git a/cli/command_line.cpp b/cli/command_line.cpp index ff6c928..3e92a20 100644 --- a/cli/command_line.cpp +++ b/cli/command_line.cpp @@ -30,6 +30,25 @@ namespace katja const std::vector arguments; }; + export struct search_command + { + const std::string needle; + }; + + export struct updates_command + { + }; + + export struct help_command + { + }; + + export using subcommand = std::variant< + search_command, + updates_command, + help_command + >; + export class invalid_command_error : public std::runtime_error { const std::string command; @@ -40,13 +59,26 @@ namespace katja { } - invalid_command_error(const std::string& invalid_command) + explicit invalid_command_error(const std::string& invalid_command) : command{ invalid_command }, std::runtime_error("Unknown command given on the command line.") { } }; + export class command_line_error : public std::runtime_error + { + boost::program_options::options_description description; + + public: + command_line_error(const std::string& message, + boost::program_options::options_description&& description) + : description(std::move(description)), + std::runtime_error(message) + { + } + }; + export command_line parse_command_line(int argc, const char **argv) { if (argc == 1) @@ -70,4 +102,42 @@ namespace katja } throw invalid_command_error(argv[1]); } + + search_command parse_search_command(const std::vector& arguments) + { + boost::program_options::options_description search_description("Search packages"); + search_description + .add_options()("name", "Find packages by name"); + + boost::program_options::positional_options_description positional_arguments; + positional_arguments.add("name", 1); + + boost::program_options::variables_map option_map; + auto command_parser = boost::program_options::command_line_parser(arguments) + .options(search_description).positional(positional_arguments); + boost::program_options::store(command_parser.run(), option_map); + boost::program_options::notify(option_map); + + if (!option_map.count("name")) + { + throw command_line_error("Search string wasn't specified.", + std::move(search_description)); + } + return search_command{ option_map["name"].as() }; + } + + export subcommand parse_subcommand(const command_line& subcommand_line) + { + switch (subcommand_line.type) + { + case command::updates: + return updates_command(); + case command::search: + return parse_search_command(subcommand_line.arguments); + case command::help: + return help_command(); + default: + std::unreachable(); + } + } } -- cgit v1.2.3