Add `switch` command
Change-Id: I5db53925f1710e29b49398621e6b634889f1df15
diff --git a/src/ast_commands.cpp b/src/ast_commands.cpp
index fa2b56c..74aefd5 100644
--- a/src/ast_commands.cpp
+++ b/src/ast_commands.cpp
@@ -56,3 +56,8 @@
{
return this->m_path == other.m_path;
}
+
+bool switch_::operator==(const switch_& other) const
+{
+ return this->m_target == other.m_target;
+}
diff --git a/src/ast_commands.hpp b/src/ast_commands.hpp
index 9ec2740..d0a3f3e 100644
--- a/src/ast_commands.hpp
+++ b/src/ast_commands.hpp
@@ -11,6 +11,7 @@
#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
#include "ast_path.hpp"
#include "ast_values.hpp"
+#include "datastore_access.hpp"
#include "yang_operations.hpp"
namespace x3 = boost::spirit::x3;
@@ -287,8 +288,32 @@
bool operator==(const cancel_& other) const;
};
+struct switch_ : x3::position_tagged {
+ static constexpr auto name = "switch";
+ static constexpr auto shortHelp = "switch - Switch datastore target.";
+ static constexpr auto longHelp = R"(
+ switch <target>
+
+ This command switches the datastore target. Available targets are:
+
+ operational:
+ - reads from operational, writes to running
+ startup:
+ - reads from startup, writes to startup
+ running:
+ - reads from running, writes to running
+
+
+ Usage:
+ /> switch running
+ /> switch startup
+ /> switch operational)";
+ bool operator==(const switch_& other) const;
+ DatastoreTarget m_target;
+};
+
struct help_;
-using CommandTypes = boost::mpl::vector<cancel_, cd_, commit_, copy_, create_, delete_, describe_, discard_, dump_, exec_, get_, help_, ls_, move_, prepare_, set_>;
+using CommandTypes = boost::mpl::vector<cancel_, cd_, commit_, copy_, create_, delete_, describe_, discard_, dump_, exec_, get_, help_, ls_, move_, prepare_, set_, switch_>;
struct help_ : x3::position_tagged {
static constexpr auto name = "help";
static constexpr auto shortHelp = "help - Print help for commands.";
@@ -339,3 +364,4 @@
BOOST_FUSION_ADAPT_STRUCT(dump_, m_format)
BOOST_FUSION_ADAPT_STRUCT(prepare_, m_path)
BOOST_FUSION_ADAPT_STRUCT(exec_, m_path)
+BOOST_FUSION_ADAPT_STRUCT(switch_, m_target)
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index 686af85..288801d 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -270,6 +270,8 @@
struct exec_class;
+struct switch_class;
+
struct cancel_class;
struct command_class {
diff --git a/src/grammars.hpp b/src/grammars.hpp
index e86748c..efc9a54 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -31,6 +31,7 @@
x3::rule<dump_class, dump_> const dump = "dump";
x3::rule<prepare_class, prepare_> const prepare = "prepare";
x3::rule<exec_class, exec_> const exec = "exec";
+x3::rule<switch_class, exec_> const switch_rule = "switch";
x3::rule<cancel_class, cancel_> const cancel = "cancel";
x3::rule<command_class, command_> const command = "command";
@@ -139,8 +140,8 @@
auto const describe_def =
describe_::name >> space_separator > anyPath;
-struct mode_table : x3::symbols<MoveMode> {
- mode_table()
+struct move_mode_table : x3::symbols<MoveMode> {
+ move_mode_table()
{
add
("after", MoveMode::After)
@@ -148,7 +149,7 @@
("begin", MoveMode::Begin)
("end", MoveMode::End);
}
-} const mode_table;
+} const move_mode_table;
struct move_absolute_table : x3::symbols<yang::move::Absolute> {
move_absolute_table()
@@ -264,6 +265,25 @@
auto const exec_def =
exec_::name > -(space_separator > -as<dataPath_>[RpcActionPath<AllowInput::No>{}]);
+const auto dsTargetSuggestions = x3::eps[([](auto& ctx) {
+ auto& parserContext = x3::get<parser_context_tag>(ctx);
+ parserContext.m_suggestions = {Completion{"running", " "}, Completion{"startup", " "}, Completion{"operational", " "}};
+ parserContext.m_completionIterator = _where(ctx).begin();
+})];
+
+struct ds_target_table : x3::symbols<DatastoreTarget> {
+ ds_target_table()
+ {
+ add
+ ("operational", DatastoreTarget::Operational)
+ ("startup", DatastoreTarget::Startup)
+ ("running", DatastoreTarget::Running);
+ }
+} const ds_target_table;
+
+auto const switch_rule_def =
+ switch_::name > space_separator > dsTargetSuggestions > ds_target_table;
+
auto const cancel_def =
cancel_::name >> x3::attr(cancel_{});
@@ -274,7 +294,7 @@
x3::eps;
auto const command_def =
- createCommandSuggestions >> x3::expect[cd | copy | create | delete_rule | set | commit | get | ls | discard | describe | help | move | dump | prepare | exec | cancel];
+ createCommandSuggestions >> x3::expect[cd | copy | create | delete_rule | set | commit | get | ls | discard | describe | help | move | dump | prepare | exec | cancel | switch_rule];
#if __clang__
#pragma GCC diagnostic pop
@@ -295,6 +315,7 @@
BOOST_SPIRIT_DEFINE(dump)
BOOST_SPIRIT_DEFINE(prepare)
BOOST_SPIRIT_DEFINE(exec)
+BOOST_SPIRIT_DEFINE(switch_rule)
BOOST_SPIRIT_DEFINE(cancel)
BOOST_SPIRIT_DEFINE(command)
BOOST_SPIRIT_DEFINE(createCommandSuggestions)
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index 3f8edc7..43e2269 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -247,6 +247,11 @@
m_datastore.cancel();
}
+void Interpreter::operator()(const switch_& switch_cmd) const
+{
+ m_datastore.setTarget(switch_cmd.m_target);
+}
+
struct commandLongHelpVisitor : boost::static_visitor<const char*> {
template <typename T>
auto constexpr operator()(boost::type<T>) const
diff --git a/src/interpreter.hpp b/src/interpreter.hpp
index c59e3d2..36c9388 100644
--- a/src/interpreter.hpp
+++ b/src/interpreter.hpp
@@ -32,6 +32,7 @@
void operator()(const prepare_& prepare) const;
void operator()(const exec_& exec) const;
void operator()(const cancel_& cancel) const;
+ void operator()(const switch_& switch_cmd) const;
private:
[[nodiscard]] std::string buildTypeInfo(const std::string& path) const;
diff --git a/src/proxy_datastore.cpp b/src/proxy_datastore.cpp
index 8f86831..3bd6719 100644
--- a/src/proxy_datastore.cpp
+++ b/src/proxy_datastore.cpp
@@ -107,3 +107,8 @@
return m_inputDatastore;
}
}
+
+void ProxyDatastore::setTarget(const DatastoreTarget target)
+{
+ m_datastore->setTarget(target);
+}
diff --git a/src/proxy_datastore.hpp b/src/proxy_datastore.hpp
index f084a2d..21fbfc5 100644
--- a/src/proxy_datastore.hpp
+++ b/src/proxy_datastore.hpp
@@ -28,6 +28,7 @@
void discardChanges();
void copyConfig(const Datastore source, const Datastore destination);
[[nodiscard]] std::string dump(const DataFormat format) const;
+ void setTarget(const DatastoreTarget target);
void initiate(const std::string& path);
[[nodiscard]] DatastoreAccess::Tree execute();
diff --git a/tests/command_completion.cpp b/tests/command_completion.cpp
index c92bad0..8e8570f 100644
--- a/tests/command_completion.cpp
+++ b/tests/command_completion.cpp
@@ -21,7 +21,7 @@
int expectedContextLength;
SECTION("no prefix")
{
- expectedCompletions = {"cd", "copy", "create", "delete", "set", "commit", "get", "ls", "discard", "help", "describe", "move", "dump", "prepare", "exec", "cancel"};
+ expectedCompletions = {"cd", "copy", "create", "delete", "set", "commit", "get", "ls", "discard", "help", "describe", "move", "dump", "prepare", "exec", "cancel", "switch"};
expectedContextLength = 0;
SECTION("no space")
{
@@ -75,6 +75,13 @@
expectedContextLength = 0;
}
+ SECTION("switch datastore targets")
+ {
+ input = "switch ";
+ expectedCompletions = {"running", "startup", "operational"};
+ expectedContextLength = 0;
+ }
+
SECTION("dump")
{
input = "dump ";