Skip to content

Commit 32b200e

Browse files
Add Module::child(), Module::childrenDfs() and Module::immediateChildren()
Those functions are implemented in the same manner as in `SchemaNode` and allows to walk through modules children. This is counterpart to already implemented `Module::childInstantiables()` that returns instantiables schema nodes. These return all nodes, including the schema-only nodes such as choice and case if end-user needs to read its schema. While the implementation is inspired by functions in `SchemaNode`, imlementation of `Module::parent()` and `Module::siblings()` was omitted as those do no make sense on `Module`. Change-Id: I38c8374304f859d65343d04d08302e07deb05f27
1 parent 01f2633 commit 32b200e

File tree

6 files changed

+346
-135
lines changed

6 files changed

+346
-135
lines changed

include/libyang-cpp/Collection.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class LIBYANG_CPP_EXPORT Collection {
9898
public:
9999
friend DataNode;
100100
friend Iterator<NodeType, ITER_TYPE>;
101+
friend Module;
101102
friend SchemaNode;
102103
~Collection();
103104
Collection(const Collection<NodeType, ITER_TYPE>&);

include/libyang-cpp/Module.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class ChildInstanstiables;
3434
class Identity;
3535
class SchemaNode;
3636
class SubmoduleParsed;
37+
template <typename NodeType, IterationType ITER_TYPE>
38+
class Collection;
3739

3840
namespace types {
3941
class IdentityRef;
@@ -86,7 +88,10 @@ class LIBYANG_CPP_EXPORT Module {
8688

8789
std::vector<Identity> identities() const;
8890

91+
std::optional<SchemaNode> child() const;
8992
ChildInstanstiables childInstantiables() const;
93+
libyang::Collection<SchemaNode, IterationType::Dfs> childrenDfs() const;
94+
Collection<SchemaNode, IterationType::Sibling> immediateChildren() const;
9095
std::vector<SchemaNode> actionRpcs() const;
9196

9297
std::string printStr(const SchemaOutputFormat format, const std::optional<SchemaPrintFlags> flags = std::nullopt, std::optional<size_t> lineLength = std::nullopt) const;

src/Module.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <algorithm>
1010
#include <libyang-cpp/ChildInstantiables.hpp>
11+
#include <libyang-cpp/Collection.hpp>
1112
#include <libyang-cpp/Module.hpp>
1213
#include <libyang-cpp/Utils.hpp>
1314
#include <libyang/libyang.h>
@@ -178,6 +179,23 @@ std::vector<Identity> Module::identities() const
178179
return res;
179180
}
180181

182+
/**
183+
* @brief Returns the first child node of this module.
184+
* @return The child, or std::nullopt if there are no children.
185+
*/
186+
std::optional<SchemaNode> Module::child() const
187+
{
188+
if (!m_module->implemented) {
189+
throw Error{"Module::child: module is not implemented"};
190+
}
191+
192+
if (!m_module->compiled->data) {
193+
return std::nullopt;
194+
}
195+
196+
return SchemaNode{m_module->compiled->data, m_ctx};
197+
}
198+
181199
/**
182200
* @brief Returns a collection of data instantiable top-level nodes of this module.
183201
*
@@ -191,6 +209,28 @@ ChildInstanstiables Module::childInstantiables() const
191209
return ChildInstanstiables{nullptr, m_module->compiled, m_ctx};
192210
}
193211

212+
/**
213+
* @brief Returns a collection for iterating depth-first over the subtree this module points to.
214+
*/
215+
Collection<SchemaNode, IterationType::Dfs> Module::childrenDfs() const
216+
{
217+
if (!m_module->implemented) {
218+
throw Error{"Module::childrenDfs: module is not implemented"};
219+
}
220+
return Collection<SchemaNode, IterationType::Dfs>{m_module->compiled->data, m_ctx};
221+
}
222+
223+
/**
224+
* @brief Returns a collection for iterating over the immediate children of where this module points to.
225+
*
226+
* This is a convenience function for iterating over this->child().siblings() which does not throw even when module has no children.
227+
*/
228+
Collection<SchemaNode, IterationType::Sibling> Module::immediateChildren() const
229+
{
230+
auto c = child();
231+
return c ? c->siblings() : Collection<SchemaNode, IterationType::Sibling>{nullptr, nullptr};
232+
}
233+
194234
/**
195235
* @brief Returns a collection of RPC nodes (not action nodes) as SchemaNode
196236
*

tests/context.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,11 @@ TEST_CASE("context")
713713
+--rw anydataWithMandatoryChild anydata
714714
+--rw anyxmlBasic? anyxml
715715
+--rw anyxmlWithMandatoryChild anyxml
716+
+--rw (choiceOnModule)?
717+
| +--:(case1)
718+
| | +--rw choiceOnModuleLeaf1? string
719+
| +--:(case2)
720+
| +--rw choiceOnModuleLeaf2? string
716721
+--rw choiceBasicContainer
717722
| +--rw (choiceBasic)?
718723
| +--:(case1)

tests/example_schema.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,19 @@ module type_module {
390390
mandatory true;
391391
}
392392
393+
choice choiceOnModule {
394+
case case1 {
395+
leaf choiceOnModuleLeaf1 {
396+
type string;
397+
}
398+
}
399+
case case2 {
400+
leaf choiceOnModuleLeaf2 {
401+
type string;
402+
}
403+
}
404+
}
405+
393406
container choiceBasicContainer {
394407
choice choiceBasic {
395408
case case1 {
@@ -787,6 +800,14 @@ module type_module {
787800
}
788801
)"s;
789802

803+
const auto empty_module = R"(
804+
module empty_module {
805+
yang-version 1.1;
806+
namespace "e";
807+
prefix "e";
808+
}
809+
)"s;
810+
790811
const auto with_inet_types_module = R"(
791812
module with-inet-types {
792813
yang-version 1.1;

0 commit comments

Comments
 (0)