Mercurial > irccd
view lib/irccd/command/command.h @ 72:98ac3c79009f
Irccd: start making a library, #429
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 24 Mar 2016 14:07:30 +0100 |
parents | |
children | 8ee1178f1219 |
line wrap: on
line source
#ifndef _REMOTE_COMMAND_H_ #define _REMOTE_COMMAND_H_ #include <cassert> #include <cstdint> #include <map> #include <vector> #include <irccd/json.h> namespace irccd { class Irccd; class Irccdctl; /** * @class RemoteCommandOption * @brief Describe a command line option */ class RemoteCommandOption { public: enum { Argument = (1 << 0) //!< option requires an argument }; private: std::string m_id; std::string m_simple; std::string m_long; std::string m_description; std::uint8_t m_flags; public: /** * Constructor an option description. * * @pre id must not be empty * @pre at least simpleKey or longKey must not be empty * @pre description must not be empty * @param key the key the option key * @param description the description * @param flags the optional flags */ inline RemoteCommandOption(std::string id, std::string simpleKey, std::string longKey, std::string description, std::uint8_t flags = 0) noexcept : m_id(std::move(id)) , m_simple(std::move(simpleKey)) , m_long(std::move(longKey)) , m_description(std::move(description)) , m_flags(flags) { assert(!m_id.empty()); assert(!m_simple.empty() || !m_long.empty()); assert(!m_description.empty()); } /** * Get the id. * * @return the id */ inline const std::string &id() const noexcept { return m_id; } /** * Get the option key. * * @return the key */ inline const std::string &simpleKey() const noexcept { return m_simple; } /** * Get the long option. * * @return the long option */ inline const std::string &longKey() const noexcept { return m_long; } /** * Get the option description. * * @return the description */ inline const std::string &description() const noexcept { return m_description; } /** * Get the option flags. * * @return the flags */ inline std::uint8_t flags() const noexcept { return m_flags; } }; /** * @brief List of command line options. */ using RemoteCommandOptions = std::vector<RemoteCommandOption>; using RemoteCommandArg = std::pair<std::string, bool>; /** * @brief List of arguments to pass to the command. * * Any argument must have a non-empty name an can be optional if the boolean is set to false. */ using RemoteCommandArgs = std::vector<std::pair<std::string, bool>>; class RemoteCommandRequest { private: std::multimap<std::string, std::string> m_options; std::vector<std::string> m_args; public: inline RemoteCommandRequest(std::multimap<std::string, std::string> options, std::vector<std::string> args) noexcept : m_options(std::move(options)) , m_args(std::move(args)) { } inline const std::vector<std::string> &args() const noexcept { return m_args; } inline const std::multimap<std::string, std::string> &options() const noexcept { return m_options; } inline unsigned length() const noexcept { return m_args.size(); } inline bool has(const std::string &option) const noexcept { return m_options.count(option) != 0; } const std::string &arg(unsigned index) const noexcept; std::string argOr(unsigned index, std::string defaultValue) const noexcept; const std::string &option(const std::string &key) const noexcept; std::string optionOr(const std::string &key, std::string defaultValue) const noexcept; }; class RemoteCommand { private: std::string m_name; std::string m_category; bool m_visible; public: inline RemoteCommand(std::string name, std::string category, bool visible = true) noexcept : m_name(std::move(name)) , m_category(std::move(category)) , m_visible(visible) { assert(!m_name.empty()); assert(!m_category.empty()); } /** * Default destructor virtual. */ virtual ~RemoteCommand() = default; /** * Return the command name, must not have spaces. * * @return the command name */ inline const std::string &name() const noexcept { return m_name; } /** * Get the command category. * * Irccdctl will sort commands by categories. * * @return the category */ inline const std::string &category() const noexcept { return m_category; } /** * Hide the command in non-verbose mode. * * @return true if the command should be visible in non-verbose mode */ inline bool visible() const noexcept { return m_visible; } /** * Return the command usage, without the prefix. (e.g. host port). * * Options are prepended automatically * * @return the usage */ std::string usage() const; /** * Return the help message for irccdctl invocation. * * @return the help */ virtual std::string help() const = 0; /** * Get the supported irccdctl options. * * @return the options */ virtual RemoteCommandOptions options() const { return RemoteCommandOptions(); } /** * Get the supported arguments. * * @return the arguments */ virtual RemoteCommandArgs args() const { return RemoteCommandArgs(); } /** * Prepare a JSON request to the daemon. * * If the command is local and does not need to send anything to irccd's instance, return a null JSON value. * * The default implementation just send the command name with no arguments. * * @param irccdctl the irccdctl instance * @param args the command line arguments and options * @return the JSON object to send to the daemon * @post the returned JSON value must be an object */ virtual json::Value request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const; /** * Execute the command in the daemon. * * The user can return an object with any properties to forward to the client. Irccd will automatically * add the command name and the appropriate status code. * * The default return an empty object which indicates success. * * If any exception is thrown from this function, it is forwarded to the client as error status. * * @param irccd the instance * @param request the JSON request * @return the response */ virtual json::Value exec(Irccd &irccd, const json::Value &request) const; /** * What to do when receiving the response from irccd. * * This default implementation just check for an error string and shows it if any. * * @param irccdctl the irccdctl instane * @param object the result */ virtual void result(Irccdctl &irccdctl, const json::Value &response) const; }; } // !irccd #endif // !_REMOTE_COMMAND_H_