Fix `switch` parsing

There are actually two fixes: the first one is a direct fix to the
linked issue. The attribute of the rule for switch was wrong. I'm not
sure how I missed that, but OK, now we have tests.

The other bug:
For some reason, the completion generator prevented the symbol table
parser from running and the value inside the resulting switch_ was
undefined. Asserting the attribute of the completion generator seems to
solve the issue.

I thought this would have something to do with the fact that I'm using
single member fusion structs. However, the bug still persisted even when
converting them into non-fusion structs (as suggested in the first
issue).

At some point, all single-member fusion structs should be converted into
non-fusion structs, but because it doesn't solve my problem, I won't be
doing it now.

Issue: https://github.com/boostorg/spirit/issues/463
Issue: https://github.com/boostorg/spirit/issues/659
Issue: https://tree.taiga.io/project/jktjkt-netconf-cli/issue/218
Change-Id: I364b32b76741c198808cc2b3c5027913162d0703
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7880545..25ce39e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -348,6 +348,7 @@
     target_link_libraries(test_path_utils path)
     cli_test(keyvalue_completion)
     cli_test(parser_rpc)
+    cli_test(misc_commands)
 
     configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tests/init_datastore.bash.in
         ${CMAKE_CURRENT_BINARY_DIR}/init_datastore.bash @ONLY)
diff --git a/src/grammars.hpp b/src/grammars.hpp
index efc9a54..dc116a9 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -31,7 +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<switch_class, switch_> const switch_rule = "switch";
 x3::rule<cancel_class, cancel_> const cancel = "cancel";
 x3::rule<command_class, command_> const command = "command";
 
@@ -282,7 +282,7 @@
 } const ds_target_table;
 
 auto const switch_rule_def =
-    switch_::name > space_separator > dsTargetSuggestions > ds_target_table;
+    switch_::name > space_separator > as<x3::unused_type>[dsTargetSuggestions] > ds_target_table;
 
 auto const cancel_def =
     cancel_::name >> x3::attr(cancel_{});
diff --git a/tests/misc_commands.cpp b/tests/misc_commands.cpp
new file mode 100644
index 0000000..868189d
--- /dev/null
+++ b/tests/misc_commands.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 CESNET, https://photonics.cesnet.cz/
+ *
+ * Written by Václav Kubernát <kubervac@cesnet.cz>
+ *
+*/
+
+#include "trompeloeil_doctest.hpp"
+#include "parser.hpp"
+#include "pretty_printers.hpp"
+#include "static_schema.hpp"
+
+TEST_CASE("miscellaneous commands")
+{
+    auto schema = std::make_shared<StaticSchema>();
+    Parser parser(schema);
+    std::ostringstream errorStream;
+    SECTION("switch")
+    {
+        std::string input;
+        switch_ expected;
+        SECTION("operational")
+        {
+            expected.m_target = DatastoreTarget::Operational;
+            input = "switch operational";
+        }
+
+        SECTION("running")
+        {
+            expected.m_target = DatastoreTarget::Running;
+            input = "switch running";
+        }
+
+        SECTION("startup")
+        {
+            expected.m_target = DatastoreTarget::Startup;
+            input = "switch startup";
+        }
+        REQUIRE(boost::get<switch_>(parser.parseCommand(input, errorStream)) == expected);
+    }
+}