Change return value of Schema::childNodes
I'll need to use this method to generate what can be parsed as paths in
the upcoming path parser rework. As a side effect, path completion
generation gets a little bit simpler, because now I don't have to parse
the strings of format "[module:]node" and just trust whatever the schema
gives me.
Change-Id: I881cdbbd8254b846c21cee1ac0a3b7af1e40a696
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index 5f7b922..2a1b360 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -461,27 +461,20 @@
auto suggestions = schema.availableNodes(parserContext.currentSchemaPath(), Recursion::NonRecursive);
std::set<Completion> suffixesAdded;
std::transform(suggestions.begin(), suggestions.end(),
- std::inserter(suffixesAdded, suffixesAdded.end()),
- [&parserContext, &schema] (auto it) {
- ModuleNodePair node;
- if (auto colonPos = it.find(":"); colonPos != it.npos) {
- node.first = it.substr(0, colonPos);
- node.second = it.substr(colonPos + 1, node.second.npos);
- } else {
- node.first = boost::none;
- node.second = it;
- }
+ std::inserter(suffixesAdded, suffixesAdded.end()),
+ [&parserContext, &schema](const ModuleNodePair& node) {
+ std::string completion = (node.first ? *node.first + ":" : "") + node.second;
- if (schema.isLeaf(parserContext.currentSchemaPath(), node)) {
- return Completion{it + " "};
- }
- if (schema.isContainer(parserContext.currentSchemaPath(), node)) {
- return Completion{it + "/"};
- }
- if (schema.isList(parserContext.currentSchemaPath(), node)) {
- return Completion{it, "[", Completion::WhenToAdd::IfFullMatch};
- }
- return Completion{it};
+ if (schema.isLeaf(parserContext.currentSchemaPath(), node)) {
+ return Completion{completion + " "};
+ }
+ if (schema.isContainer(parserContext.currentSchemaPath(), node)) {
+ return Completion{completion + "/"};
+ }
+ if (schema.isList(parserContext.currentSchemaPath(), node)) {
+ return Completion{completion, "[", Completion::WhenToAdd::IfFullMatch};
+ }
+ return Completion{completion};
});
parserContext.m_suggestions = suffixesAdded;
}
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index 9912584..0a4f59e 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -76,7 +76,7 @@
recursion = Recursion::Recursive;
}
- std::set<std::string> toPrint;
+ std::set<ModuleNodePair> toPrint;
auto pathArg = dataPathToSchemaPath(m_parser.currentPath());
if (ls.m_path) {
@@ -95,8 +95,9 @@
toPrint = m_datastore.schema()->availableNodes(pathArg, recursion);
}
- for (const auto& it : toPrint)
- std::cout << it << std::endl;
+ for (const auto& it : toPrint) {
+ std::cout << (it.first ? *it.first + ":" : "" ) + it.second << std::endl;
+ }
}
void Interpreter::operator()(const copy_& copy) const
diff --git a/src/schema.hpp b/src/schema.hpp
index 4dd9a2a..052386e 100644
--- a/src/schema.hpp
+++ b/src/schema.hpp
@@ -70,5 +70,5 @@
virtual std::optional<std::string> description(const std::string& location) const = 0;
virtual yang::Status status(const std::string& location) const = 0;
- virtual std::set<std::string> availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const = 0;
+ virtual std::set<ModuleNodePair> availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const = 0;
};
diff --git a/src/static_schema.cpp b/src/static_schema.cpp
index 2f1dcb2..082d03b 100644
--- a/src/static_schema.cpp
+++ b/src/static_schema.cpp
@@ -135,19 +135,28 @@
return boost::get<yang::leaf>(children(locationString).at(node)).m_type;
}
-std::set<std::string> StaticSchema::availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const
+ModuleNodePair splitModuleNode(const std::string& input)
+{
+ auto colonLocation = input.find_first_of(':');
+ if (colonLocation != std::string::npos) {
+ return ModuleNodePair{input.substr(0, colonLocation), input.substr(colonLocation + 1)};
+ }
+ throw std::logic_error("Tried to split a string without a colon (StaticSchema node names should always be stored with prefixes)");
+}
+
+std::set<ModuleNodePair> StaticSchema::availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const
{
if (recursion == Recursion::Recursive) {
throw std::logic_error("Recursive StaticSchema::availableNodes is not implemented. It shouldn't be used in tests.");
}
- std::set<std::string> res;
+ std::set<ModuleNodePair> res;
if (path.type() == typeid(module_)) {
auto topLevelNodes = m_nodes.at("");
auto modulePlusColon = boost::get<module_>(path).m_name + ":";
for (const auto& it : topLevelNodes) {
if (boost::algorithm::starts_with(it.first, modulePlusColon)) {
- res.insert(it.first);
+ res.insert(splitModuleNode(it.first));
}
}
return res;
@@ -160,7 +169,9 @@
auto childrenRef = children(locationString);
- std::transform(childrenRef.begin(), childrenRef.end(), std::inserter(res, res.end()), [](auto it) { return it.first; });
+ std::transform(childrenRef.begin(), childrenRef.end(), std::inserter(res, res.end()), [](const auto& it) {
+ return splitModuleNode(it.first);
+ });
return res;
}
diff --git a/src/static_schema.hpp b/src/static_schema.hpp
index 43f7b8d..67bd7b9 100644
--- a/src/static_schema.hpp
+++ b/src/static_schema.hpp
@@ -57,7 +57,7 @@
yang::TypeInfo leafType(const std::string& path) const override;
std::optional<std::string> leafTypeName(const std::string& path) const override;
std::string leafrefPath(const std::string& leafrefPath) const override;
- std::set<std::string> availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const override;
+ std::set<ModuleNodePair> availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const override;
std::optional<std::string> description(const std::string& path) const override;
yang::Status status(const std::string& location) const override;
diff --git a/src/yang_schema.cpp b/src/yang_schema.cpp
index 80ec7f3..2c8b30d 100644
--- a/src/yang_schema.cpp
+++ b/src/yang_schema.cpp
@@ -320,10 +320,10 @@
return res;
}
-std::set<std::string> YangSchema::availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const
+std::set<ModuleNodePair> YangSchema::availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const
{
using namespace std::string_view_literals;
- std::set<std::string> res;
+ std::set<ModuleNodePair> res;
std::vector<libyang::S_Schema_Node> nodes;
std::string topLevelModule;
@@ -351,15 +351,14 @@
continue;
if (recursion == Recursion::Recursive) {
for (auto it : node->tree_dfs()) {
- res.insert(it->path(LYS_PATH_FIRST_PREFIX));
+ res.insert(ModuleNodePair(boost::none, it->path(LYS_PATH_FIRST_PREFIX)));
}
} else {
- std::string toInsert;
+ ModuleNodePair toInsert;
if (topLevelModule.empty() || topLevelModule != node->module()->name()) {
- toInsert += node->module()->name();
- toInsert += ":";
+ toInsert.first = node->module()->name();
}
- toInsert += node->name();
+ toInsert.second = node->name();
res.insert(toInsert);
}
}
diff --git a/src/yang_schema.hpp b/src/yang_schema.hpp
index 9395ba2..2a93b07 100644
--- a/src/yang_schema.hpp
+++ b/src/yang_schema.hpp
@@ -43,7 +43,7 @@
yang::TypeInfo leafType(const std::string& path) const override;
std::optional<std::string> leafTypeName(const std::string& path) const override;
std::string leafrefPath(const std::string& leafrefPath) const override;
- std::set<std::string> availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const override;
+ std::set<ModuleNodePair> availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const override;
std::optional<std::string> description(const std::string& path) const override;
yang::Status status(const std::string& location) const override;