Add special type for representing special values
Before this, pseudo-values like lists and containers were represented by
a string leaf value. Now, I can tell these values apart. This can be
helpful for filtering (for example, when printing the values). It will
also be used for implementing key value completion.
Change-Id: I48f6fa2facaf3e8e52aa3b3b4d92130e63acdb6f
diff --git a/src/ast_values.cpp b/src/ast_values.cpp
index b8ca68d..8d9c40c 100644
--- a/src/ast_values.cpp
+++ b/src/ast_values.cpp
@@ -48,3 +48,21 @@
return this->m_value == b.m_value;
}
+bool special_::operator==(const special_& b) const
+{
+ return this->m_value == b.m_value;
+}
+
+std::string specialValueToString(const special_& value)
+{
+ switch (value.m_value) {
+ case SpecialValue::Container:
+ return "(container)";
+ case SpecialValue::PresenceContainer:
+ return "(presence container)";
+ case SpecialValue::List:
+ return "(list)";
+ }
+
+ __builtin_unreachable();
+}
diff --git a/src/ast_values.hpp b/src/ast_values.hpp
index 44e98af..b2f2c3a 100644
--- a/src/ast_values.hpp
+++ b/src/ast_values.hpp
@@ -38,9 +38,23 @@
std::string m_value;
};
+enum class SpecialValue {
+ List,
+ Container,
+ PresenceContainer
+};
+
+struct special_ {
+ bool operator==(const special_& b) const;
+ SpecialValue m_value;
+};
+
+std::string specialValueToString(const special_& value);
+
using leaf_data_ = boost::variant<enum_,
binary_,
identityRef_,
+ special_,
double,
bool,
int8_t,
diff --git a/src/netconf_access.cpp b/src/netconf_access.cpp
index d1619cb..78d80b1 100644
--- a/src/netconf_access.cpp
+++ b/src/netconf_access.cpp
@@ -58,7 +58,7 @@
if (!it)
continue;
if (it->schema()->nodetype() == LYS_LIST) {
- res.emplace(it->path(), std::string{"(list)"});
+ res.emplace(it->path(), special_{SpecialValue::List});
}
if (it->schema()->nodetype() == LYS_LEAF) {
libyang::Data_Node_Leaf_List leaf(it);
diff --git a/src/sysrepo_access.cpp b/src/sysrepo_access.cpp
index b01b484..221f482 100644
--- a/src/sysrepo_access.cpp
+++ b/src/sysrepo_access.cpp
@@ -39,11 +39,11 @@
case SR_DECIMAL64_T:
return value->data()->get_decimal64();
case SR_CONTAINER_T:
- return "(container)"s;
+ return special_{SpecialValue::Container};
case SR_CONTAINER_PRESENCE_T:
- return "(presence container)"s;
+ return special_{SpecialValue::PresenceContainer};
case SR_LIST_T:
- return "(list)"s;
+ return special_{SpecialValue::List};
default: // TODO: implement all types
return value->val_to_string();
}
@@ -66,6 +66,11 @@
return std::make_shared<sysrepo::Val>(res.c_str(), SR_IDENTITYREF_T);
}
+ sysrepo::S_Val operator()(const special_& value) const
+ {
+ throw std::runtime_error("Tried constructing S_Val from a " + specialValueToString(value));
+ }
+
sysrepo::S_Val operator()(const std::string& value) const
{
return std::make_shared<sysrepo::Val>(value.c_str());
diff --git a/src/utils.cpp b/src/utils.cpp
index 672cd36..eb4f432 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -108,6 +108,11 @@
return data.m_prefix.value().m_name + ":" + data.m_value;
}
+ std::string operator()(const special_& data) const
+ {
+ return specialValueToString(data);
+ }
+
std::string operator()(const std::string& data) const
{
return data;
diff --git a/tests/datastore_access.cpp b/tests/datastore_access.cpp
index 09801b2..535abdc 100644
--- a/tests/datastore_access.cpp
+++ b/tests/datastore_access.cpp
@@ -207,7 +207,7 @@
// because it'll use the same data structure as libnetconf, so the
// results will be consistent.
#ifdef sysrepo_BACKEND
- {"/example-schema:lol", std::string{"(container)"}},
+ {"/example-schema:lol", special_{SpecialValue::Container}},
#endif
{"/example-schema:up", bool{true}}};
REQUIRE(datastore.getItems("/example-schema:*") == expected);
@@ -240,11 +240,11 @@
datastore.commitChanges();
}
std::map<std::string, leaf_data_> expected{
- {"/example-schema:person[name='Jan']", std::string{"(list)"}},
+ {"/example-schema:person[name='Jan']", special_{SpecialValue::List}},
{"/example-schema:person[name='Jan']/name", std::string{"Jan"}},
- {"/example-schema:person[name='Michal']", std::string{"(list)"}},
+ {"/example-schema:person[name='Michal']", special_{SpecialValue::List}},
{"/example-schema:person[name='Michal']/name", std::string{"Michal"}},
- {"/example-schema:person[name='Petr']", std::string{"(list)"}},
+ {"/example-schema:person[name='Petr']", special_{SpecialValue::List}},
{"/example-schema:person[name='Petr']/name", std::string{"Petr"}}
};