Add Schema::nodeType method
Change-Id: Id17e00ebef4820abae3b66d2e262be4b16c7a672
diff --git a/src/schema.hpp b/src/schema.hpp
index 8b7031a..6970fe9 100644
--- a/src/schema.hpp
+++ b/src/schema.hpp
@@ -35,6 +35,13 @@
IdentityRef,
LeafRef,
};
+
+enum class NodeTypes {
+ Container,
+ PresenceContainer,
+ List,
+ Leaf
+};
}
enum class Recursion {
@@ -43,10 +50,7 @@
};
-class InvalidNodeException : public std::invalid_argument {
-public:
- using std::invalid_argument::invalid_argument;
- ~InvalidNodeException() override;
+class InvalidNodeException {
};
/*! \class Schema
@@ -61,6 +65,8 @@
virtual bool isContainer(const schemaPath_& location, const ModuleNodePair& node) const = 0;
virtual bool isLeaf(const schemaPath_& location, const ModuleNodePair& node) const = 0;
+ virtual yang::NodeTypes nodeType(const std::string& path) const = 0;
+ virtual yang::NodeTypes nodeType(const schemaPath_& location, const ModuleNodePair& node) const = 0;
virtual bool isModule(const std::string& name) const = 0;
virtual bool isList(const schemaPath_& location, const ModuleNodePair& node) const = 0;
virtual bool isPresenceContainer(const schemaPath_& location, const ModuleNodePair& node) const = 0;
diff --git a/src/static_schema.cpp b/src/static_schema.cpp
index 47e0884..aae6b84 100644
--- a/src/static_schema.cpp
+++ b/src/static_schema.cpp
@@ -10,8 +10,6 @@
#include "static_schema.hpp"
#include "utils.hpp"
-InvalidNodeException::~InvalidNodeException() = default;
-
StaticSchema::StaticSchema()
{
m_nodes.emplace("/", std::unordered_map<std::string, NodeType>());
@@ -284,3 +282,37 @@
}
return res;
}
+
+yang::NodeTypes StaticSchema::nodeType(const schemaPath_& location, const ModuleNodePair& node) const
+{
+ std::string locationString = pathToSchemaString(location, Prefixes::Always);
+ auto fullName = fullNodeName(location, node);
+ try {
+ auto targetNode = children(locationString).at(fullName);
+
+ if (targetNode.type() == typeid(yang::container)) {
+ if (boost::get<yang::container>(targetNode).m_presence == yang::ContainerTraits::Presence) {
+ return yang::NodeTypes::PresenceContainer;
+ }
+ return yang::NodeTypes::Container;
+ }
+
+ if (targetNode.type() == typeid(yang::list)) {
+ return yang::NodeTypes::List;
+ }
+
+ if (targetNode.type() == typeid(yang::leaf)) {
+ return yang::NodeTypes::Leaf;
+ }
+
+ throw std::runtime_error{"YangSchema::nodeType: unsupported type"};
+
+ } catch (std::out_of_range&) {
+ throw InvalidNodeException();
+ }
+}
+
+yang::NodeTypes StaticSchema::nodeType([[maybe_unused]] const std::string& path) const
+{
+ throw std::runtime_error{"Internal error: StaticSchema::nodeType(std::string) not implemented. The tests should not have called this overload."};
+}
diff --git a/src/static_schema.hpp b/src/static_schema.hpp
index 742c53d..8ff3405 100644
--- a/src/static_schema.hpp
+++ b/src/static_schema.hpp
@@ -49,6 +49,8 @@
StaticSchema();
bool isContainer(const schemaPath_& location, const ModuleNodePair& node) const override;
+ yang::NodeTypes nodeType(const std::string& path) const override;
+ yang::NodeTypes nodeType(const schemaPath_& location, const ModuleNodePair& node) const override;
bool isModule(const std::string& name) const override;
bool isLeaf(const schemaPath_& location, const ModuleNodePair& node) const override;
bool isList(const schemaPath_& location, const ModuleNodePair& node) const override;
diff --git a/src/yang_schema.cpp b/src/yang_schema.cpp
index dddebf5..3470865 100644
--- a/src/yang_schema.cpp
+++ b/src/yang_schema.cpp
@@ -412,3 +412,32 @@
{
return m_context->get_module(name.c_str(), nullptr, 0);
}
+
+namespace {
+yang::NodeTypes impl_nodeType(const libyang::S_Schema_Node& node)
+{
+ if (!node) {
+ throw InvalidNodeException();
+ }
+ switch (node->nodetype()) {
+ case LYS_CONTAINER:
+ return libyang::Schema_Node_Container{node}.presence() ? yang::NodeTypes::PresenceContainer : yang::NodeTypes::Container;
+ case LYS_LEAF:
+ return yang::NodeTypes::Leaf;
+ case LYS_LIST:
+ return yang::NodeTypes::List;
+ default:
+ throw std::runtime_error{"YangSchema::nodeType: unsupported type"};
+ }
+}
+}
+
+yang::NodeTypes YangSchema::nodeType(const schemaPath_& location, const ModuleNodePair& node) const
+{
+ return impl_nodeType(getSchemaNode(location, node));
+}
+
+yang::NodeTypes YangSchema::nodeType(const std::string& path) const
+{
+ return impl_nodeType(getSchemaNode(path));
+}
diff --git a/src/yang_schema.hpp b/src/yang_schema.hpp
index 1ff5144..dd88145 100644
--- a/src/yang_schema.hpp
+++ b/src/yang_schema.hpp
@@ -32,6 +32,8 @@
bool isContainer(const schemaPath_& location, const ModuleNodePair& node) const override;
bool isLeaf(const schemaPath_& location, const ModuleNodePair& node) const override;
+ yang::NodeTypes nodeType(const std::string& path) const override;
+ yang::NodeTypes nodeType(const schemaPath_& location, const ModuleNodePair& node) const override;
bool isModule(const std::string& name) const override;
bool isList(const schemaPath_& location, const ModuleNodePair& node) const override;
bool isPresenceContainer(const schemaPath_& location, const ModuleNodePair& node) const override;
diff --git a/tests/yang.cpp b/tests/yang.cpp
index 162a194..017107c 100644
--- a/tests/yang.cpp
+++ b/tests/yang.cpp
@@ -749,6 +749,37 @@
REQUIRE(ys.childNodes(path, Recursion::NonRecursive) == set);
}
+ SECTION("nodeType")
+ {
+ yang::NodeTypes expected;
+ SECTION("leafInt32")
+ {
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, leaf_("leafInt32")));
+ expected = yang::NodeTypes::Leaf;
+ }
+
+ SECTION("a")
+ {
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
+ expected = yang::NodeTypes::Container;
+ }
+
+ SECTION("a/a2/a3")
+ {
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
+ path.m_nodes.push_back(schemaNode_(container_("a2")));
+ path.m_nodes.push_back(schemaNode_(container_("a3")));
+ expected = yang::NodeTypes::PresenceContainer;
+ }
+
+ SECTION("_list")
+ {
+ path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, list_("_list")));
+ expected = yang::NodeTypes::List;
+ }
+
+ REQUIRE(ys.nodeType(pathToSchemaString(path, Prefixes::WhenNeeded)) == expected);
+ }
}
SECTION("negative")