Fix enum key parsing

I'm not sure if this got broken during leaf_data rework, or if it was
always broken, but enum parsing had to get reworked.

The problem was parsing enums with "+char_". This works with set,
because set doesn't have any additional arguments. However, that's not
the case with key parsing. In key parsing +char_ was eating too much of
the input (mainly the closing bracker). At first I tried something like
"+char_-']'", but enums are normal strings, so ']' is a valid character.
That's why I reworked the parser to just try all the possible enums.

Change-Id: I5996286424dd95377b55f90eeba29d9a5eba731c
diff --git a/src/leaf_data.hpp b/src/leaf_data.hpp
index e616498..fb490c7 100644
--- a/src/leaf_data.hpp
+++ b/src/leaf_data.hpp
@@ -17,7 +17,6 @@
 template <typename TYPE>
 struct leaf_data_class;
 
-x3::rule<struct leaf_data_class<yang::Enum>, enum_> const leaf_data_enum = "leaf_data_enum";
 x3::rule<struct leaf_data_class<yang::IdentityRef>, identityRef_> const leaf_data_identityRef = "leaf_data_identityRef";
 x3::rule<struct leaf_data_class<yang::Binary>, binary_> const leaf_data_binary = "leaf_data_binary";
 x3::rule<struct leaf_data_class<yang::Decimal>, double> const leaf_data_decimal = "leaf_data_decimal";
@@ -25,9 +24,6 @@
 
 using x3::char_;
 
-auto const leaf_data_enum_def =
-    +char_;
-
 struct bool_symbol_table : x3::symbols<bool> {
     bool_symbol_table()
     {
@@ -128,16 +124,18 @@
     bool operator()(const yang::Enum& type) const
     {
         createSetSuggestions(type);
-        auto checkValidEnum = [this, type] (auto& ctx) {
-            if (type.m_allowedValues.count(boost::get<enum_>(attr)) == 0) {
-                _pass(ctx) = false;
-                parserContext.m_errorMsg = "leaf data type mismatch: Expected an enum here. Allowed values:";
-                for (const auto& it : type.m_allowedValues) {
-                    parserContext.m_errorMsg += " " + it.m_value;
-                }
+        x3::symbols<enum_> parser;
+        for (const auto& value : type.m_allowedValues) {
+            parser.add(value.m_value, value);
+        }
+        auto res = parser.parse(first, last, ctx, rctx, attr);
+        if (!res) {
+            parserContext.m_errorMsg = "leaf data type mismatch: Expected an enum here. Allowed values:";
+            for (const auto& it : type.m_allowedValues) {
+                parserContext.m_errorMsg += " " + it.m_value;
             }
-        };
-        return leaf_data_enum[checkValidEnum].parse(first, last, ctx, rctx, attr);
+        }
+        return res;
     }
     bool operator()(const yang::IdentityRef& type) const
     {
@@ -188,7 +186,6 @@
 
 auto const leaf_data = x3::no_skip[LeafData()];
 
-BOOST_SPIRIT_DEFINE(leaf_data_enum)
 BOOST_SPIRIT_DEFINE(leaf_data_string)
 BOOST_SPIRIT_DEFINE(leaf_data_binary)
 BOOST_SPIRIT_DEFINE(leaf_data_identityRef)
diff --git a/tests/cd.cpp b/tests/cd.cpp
index 307f287..174ffd0 100644
--- a/tests/cd.cpp
+++ b/tests/cd.cpp
@@ -8,6 +8,7 @@
 
 #include "trompeloeil_doctest.hpp"
 #include "ast_commands.hpp"
+#include "leaf_data_helpers.hpp"
 #include "parser.hpp"
 #include "static_schema.hpp"
 
@@ -30,6 +31,8 @@
     schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
     schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
     schema->addRpc("/", "example:launch-nukes");
+    schema->addList("/", "example:ports", {"name"});
+    schema->addLeaf("/example:ports", "example:name", createEnum({"A", "B", "C"}));
     Parser parser(schema);
     std::string input;
     std::ostringstream errorStream;
@@ -124,6 +127,14 @@
                     {"name", std::string{"abcd"}}};
                 expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("twoKeyList", keys));
             }
+
+            SECTION("enum key type")
+            {
+                input = "cd example:ports[name=A]";
+                auto keys = ListInstance {
+                    {"name", enum_{"A"}}};
+                expected.m_path.m_nodes.emplace_back(module_{"example"}, listElement_("ports", keys));
+            }
         }
 
         SECTION("whitespace handling")