Add support for executing RPCs

Creating a temporary YangAccess for RPC input means I need to somehow
give the right libyang schemas. For that reason I supply a callable
which is able to fetch the schema and create a YangAccess instance for
ProxyDatastore.

The ProxyDatastore class now has a simple mechanism for deciding whether
to use the normal datastore and the temporary based on a path prefix.

Change-Id: Ib455f53237598bc2620161a44fb89c48ddfeb6e3
diff --git a/src/proxy_datastore.hpp b/src/proxy_datastore.hpp
index 0ed5e2d..c15a869 100644
--- a/src/proxy_datastore.hpp
+++ b/src/proxy_datastore.hpp
@@ -7,13 +7,18 @@
 
 #pragma once
 #include "datastore_access.hpp"
+#include "yang_access.hpp"
 
 /*! \class ProxyDatastore
  *     \brief DatastoreAccess wrapper that handles RPC input
  */
 class ProxyDatastore {
 public:
-    ProxyDatastore(const std::shared_ptr<DatastoreAccess>& datastore);
+    /**
+     * The createTemporaryDatastore function should create a temporary datastore that's going to be used for RPC input.
+     * This temporary datastore and the main datastore are supposed share the same schemas.
+     * */
+    ProxyDatastore(const std::shared_ptr<DatastoreAccess>& datastore, std::function<std::shared_ptr<DatastoreAccess>(const std::shared_ptr<DatastoreAccess>&)> createTemporaryDatastore);
     [[nodiscard]] DatastoreAccess::Tree getItems(const std::string& path) const;
     void setLeaf(const std::string& path, leaf_data_ value);
     void createItem(const std::string& path);
@@ -24,7 +29,21 @@
     void copyConfig(const Datastore source, const Datastore destination);
     [[nodiscard]] std::string dump(const DataFormat format) const;
 
+    void initiateRpc(const std::string& rpcPath);
+    [[nodiscard]] DatastoreAccess::Tree executeRpc();
+    void cancelRpc();
+
     [[nodiscard]] std::shared_ptr<Schema> schema() const;
 private:
+    /** @brief Picks a datastore based on the requested path.
+     *
+     * If the path starts with a currently processed RPC, m_inputDatastore is picked.
+     * Otherwise m_datastore is picked.
+     */
+    [[nodiscard]] std::shared_ptr<DatastoreAccess> pickDatastore(const std::string& path) const;
+
     std::shared_ptr<DatastoreAccess> m_datastore;
+    std::function<std::shared_ptr<DatastoreAccess>(const std::shared_ptr<DatastoreAccess>&)> m_createTemporaryDatastore;
+    std::shared_ptr<DatastoreAccess> m_inputDatastore;
+    std::string m_rpcPath;
 };