changeset 265:f66e56a38fd5

Irccdctl: return json values in exec() member functions, closes #537
author David Demelier <markand@malikania.fr>
date Thu, 15 Sep 2016 22:13:57 +0200
parents 4d053cd87cca
children 85a53bc2116c
files lib/irccd/cmd-plugin-load.cpp lib/irccd/cmd-plugin-load.hpp lib/irccd/cmd-plugin-reload.cpp lib/irccd/cmd-plugin-reload.hpp lib/irccd/cmd-plugin-unload.cpp lib/irccd/cmd-plugin-unload.hpp lib/irccd/irccdctl.cpp lib/irccd/irccdctl.hpp
diffstat 8 files changed, 72 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/lib/irccd/cmd-plugin-load.cpp	Thu Sep 15 17:54:31 2016 +0200
+++ b/lib/irccd/cmd-plugin-load.cpp	Thu Sep 15 22:13:57 2016 +0200
@@ -40,6 +40,11 @@
     return {{ "plugin", { nlohmann::json::value_t::string }}};
 }
 
+nlohmann::json PluginLoadCommand::request(Irccdctl &, const CommandRequest &args) const
+{
+    return nlohmann::json::object({{ "plugin", args.arg(0) }});
+}
+
 nlohmann::json PluginLoadCommand::exec(Irccd &irccd, const nlohmann::json &request) const
 {
     Command::exec(irccd, request);
--- a/lib/irccd/cmd-plugin-load.hpp	Thu Sep 15 17:54:31 2016 +0200
+++ b/lib/irccd/cmd-plugin-load.hpp	Thu Sep 15 22:13:57 2016 +0200
@@ -51,6 +51,11 @@
     IRCCD_EXPORT std::vector<Property> properties() const override;
 
     /**
+     * \copydoc Command::request
+     */
+    IRCCD_EXPORT nlohmann::json request(Irccdctl &irccdctl, const CommandRequest &args) const override;
+
+    /**
      * \copydoc Command::exec
      */
     IRCCD_EXPORT nlohmann::json exec(Irccd &irccd, const nlohmann::json &request) const override;
--- a/lib/irccd/cmd-plugin-reload.cpp	Thu Sep 15 17:54:31 2016 +0200
+++ b/lib/irccd/cmd-plugin-reload.cpp	Thu Sep 15 22:13:57 2016 +0200
@@ -41,6 +41,11 @@
     return {{ "plugin", { nlohmann::json::value_t::string }}};
 }
 
+nlohmann::json PluginReloadCommand::request(Irccdctl &, const CommandRequest &args) const
+{
+    return nlohmann::json::object({{ "plugin", args.arg(0) }});
+}
+
 nlohmann::json PluginReloadCommand::exec(Irccd &irccd, const nlohmann::json &request) const
 {
     Command::exec(irccd, request);
--- a/lib/irccd/cmd-plugin-reload.hpp	Thu Sep 15 17:54:31 2016 +0200
+++ b/lib/irccd/cmd-plugin-reload.hpp	Thu Sep 15 22:13:57 2016 +0200
@@ -51,6 +51,11 @@
     IRCCD_EXPORT std::vector<Property> properties() const override;
 
     /**
+     * \copydoc Command::request
+     */
+    IRCCD_EXPORT nlohmann::json request(Irccdctl &irccdctl, const CommandRequest &args) const override;
+
+    /**
      * \copydoc Command::exec
      */
     IRCCD_EXPORT nlohmann::json exec(Irccd &irccd, const nlohmann::json &request) const override;
--- a/lib/irccd/cmd-plugin-unload.cpp	Thu Sep 15 17:54:31 2016 +0200
+++ b/lib/irccd/cmd-plugin-unload.cpp	Thu Sep 15 22:13:57 2016 +0200
@@ -40,6 +40,11 @@
     return {{ "plugin", { nlohmann::json::value_t::string }}};
 }
 
+nlohmann::json PluginUnloadCommand::request(Irccdctl &, const CommandRequest &args) const
+{
+    return nlohmann::json::object({{ "plugin", args.arg(0) }});
+}
+
 nlohmann::json PluginUnloadCommand::exec(Irccd &irccd, const nlohmann::json &request) const
 {
     Command::exec(irccd, request);
--- a/lib/irccd/cmd-plugin-unload.hpp	Thu Sep 15 17:54:31 2016 +0200
+++ b/lib/irccd/cmd-plugin-unload.hpp	Thu Sep 15 22:13:57 2016 +0200
@@ -51,6 +51,11 @@
     IRCCD_EXPORT std::vector<Property> properties() const override;
 
     /**
+     * \copydoc Command::request
+     */
+    IRCCD_EXPORT nlohmann::json request(Irccdctl &irccdctl, const CommandRequest &args) const override;
+
+    /**
      * \copydoc Command::exec
      */
     IRCCD_EXPORT nlohmann::json exec(Irccd &irccd, const nlohmann::json &request) const override;
--- a/lib/irccd/irccdctl.cpp	Thu Sep 15 17:54:31 2016 +0200
+++ b/lib/irccd/irccdctl.cpp	Thu Sep 15 22:13:57 2016 +0200
@@ -408,7 +408,7 @@
         // Remove the previous messages.
         if (it != m_messages.end()) {
             value = *it;
-            m_messages.erase(m_messages.begin(), it);
+            m_messages.erase(m_messages.begin(), it + 1);
         }
     }
 
@@ -436,7 +436,7 @@
     return first;
 }
 
-void Irccdctl::exec(const Command &cmd, std::vector<std::string> args)
+nlohmann::json Irccdctl::exec(const Command &cmd, std::vector<std::string> args)
 {
     // 1. Build options from command line arguments.
     option::Options def;
@@ -464,29 +464,29 @@
     // 3. Check number of arguments.
     if (args.size() < cmd.min())
         throw std::runtime_error("too few arguments");
-    if (args.size() > cmd.max())
-        throw std::runtime_error("too many arguments");
 
     /*
      * 4. Construct the request, if the returned value is not an object, do not
      * send anything (e.g. help).
      */
-    nlohmann::json request = cmd.request(*this, CommandRequest(std::move(requestOptions), std::move(args)));
+    auto request = cmd.request(*this, CommandRequest(std::move(requestOptions), std::move(args)));
 
     if (!request.is_object())
-        return;
+        throw std::invalid_argument("command has returned invalid request");
 
     request.push_back({"command", cmd.name()});
 
     // 5. Send the command.
     m_connection->request(request);
 
-    // 6. Parse the result.
-    cmd.result(*this, waitMessage(cmd.name()));
+    // 6. Returns the response.
+    return waitMessage(cmd.name());
 }
 
-void Irccdctl::exec(const Alias &alias, std::vector<std::string> argsCopy)
+std::vector<nlohmann::json> Irccdctl::exec(const Alias &alias, std::vector<std::string> argsCopy)
 {
+    std::vector<nlohmann::json> values;
+
     for (const AliasCommand &cmd : alias) {
         std::vector<std::string> args(argsCopy);
         std::vector<std::string> cmdArgs;
@@ -495,7 +495,7 @@
         // 1. Append command name before.
         cmdArgs.push_back(cmd.command());
 
-        for (const AliasArg &arg : cmd.args()) {
+        for (const auto &arg : cmd.args()) {
             if (arg.isPlaceholder()) {
                 if (args.size() < arg.index() + 1)
                     throw std::invalid_argument("missing argument for placeholder %" + std::to_string(arg.index()));
@@ -517,11 +517,15 @@
         std::copy(args.begin(), args.end(), std::back_inserter(cmdArgs));
 
         // 4. Finally try to execute.
-        exec(cmdArgs);
+        auto response = exec(cmdArgs);
+
+        values.insert(values.end(), response.begin(), response.end());
     }
+
+    return values;
 }
 
-void Irccdctl::exec(std::vector<std::string> args)
+std::vector<nlohmann::json> Irccdctl::exec(std::vector<std::string> args)
 {
     assert(args.size() > 0);
 
@@ -531,16 +535,22 @@
     // Remove name.
     args.erase(args.begin());
 
-    if (alias != m_aliases.end())
-        exec(alias->second, args);
-    else {
+    std::vector<nlohmann::json> values;
+
+    if (alias != m_aliases.end()) {
+        auto response = exec(alias->second, args);
+
+        values.insert(values.end(), response.begin(), response.end());
+    } else {
         auto cmd = m_commandService.find(name);
 
         if (cmd)
-            exec(*cmd, args);
+            values.push_back(exec(*cmd, args));
         else
             throw std::invalid_argument("no alias or command named " + name);
     }
+
+    return values;
 }
 
 void Irccdctl::run(int argc, char **argv)
@@ -619,7 +629,18 @@
     for (int i = 0; i < argc; ++i)
         args.push_back(argv[i]);
 
-    exec(args);
+    auto commands = exec(args);
+
+    for (const auto &r : commands) {
+        auto name = r.find("response");
+
+        if (name == r.end() || !name->is_string())
+            log::warning() << "unknown irccd response with no response" << std::endl;
+
+        auto it = m_commandService.find(*name);
+
+        it->result(*this, r);
+    }
 }
 
 } // !irccd
--- a/lib/irccd/irccdctl.hpp	Thu Sep 15 17:54:31 2016 +0200
+++ b/lib/irccd/irccdctl.hpp	Thu Sep 15 22:13:57 2016 +0200
@@ -27,6 +27,7 @@
 #include <map>
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "client.hpp"
 #include "alias.hpp"
@@ -141,7 +142,7 @@
      * \param cmd the command
      * \param args the arguments
      */
-    IRCCD_EXPORT void exec(const Command &cmd, std::vector<std::string> args);
+    IRCCD_EXPORT nlohmann::json exec(const Command &cmd, std::vector<std::string> args);
 
     /**
      * Execute the given alias.
@@ -149,14 +150,14 @@
      * \param alias the alias
      * \param args the arguments
      */
-    IRCCD_EXPORT void exec(const Alias &alias, std::vector<std::string> args);
+    IRCCD_EXPORT std::vector<nlohmann::json> exec(const Alias &alias, std::vector<std::string> args);
 
     /**
      * Resolve the command line arguments.
      *
      * \param args the main arguments
      */
-    IRCCD_EXPORT void exec(std::vector<std::string> args);
+    IRCCD_EXPORT std::vector<nlohmann::json> exec(std::vector<std::string> args);
 
     /**
      * Run the irccdctl front end.