blob: 3630c25b0da5620608c75c779e071a8956a859ed [file] [log] [blame]
Václav Kubernát96344a12018-05-28 16:33:39 +02001/*
2 * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
3 * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
4 *
5 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
6 *
7*/
8
Václav Kubernát509ce652019-05-29 19:46:44 +02009#include <boost/mpl/for_each.hpp>
Václav Kubernátb61336d2018-05-28 17:35:03 +020010#include <iostream>
Václav Kubernát6415b822018-08-22 17:40:01 +020011#include "datastore_access.hpp"
Václav Kubernát96344a12018-05-28 16:33:39 +020012#include "interpreter.hpp"
Václav Kubernát509ce652019-05-29 19:46:44 +020013#include "utils.hpp"
Václav Kubernát96344a12018-05-28 16:33:39 +020014
Václav Kubernát812ee282018-08-30 17:10:03 +020015void Interpreter::operator()(const commit_&) const
16{
17 m_datastore.commitChanges();
18}
19
Václav Kubernát6d791432018-10-25 16:00:35 +020020void Interpreter::operator()(const discard_&) const
21{
22 m_datastore.discardChanges();
23}
24
Václav Kubernát07204242018-06-04 18:12:09 +020025void Interpreter::operator()(const set_& set) const
26{
Václav Kubernáteeb38842019-03-20 19:46:05 +010027 auto data = set.m_data;
28
29 // If the user didn't supply a module prefix for identityref, we need to add it ourselves
30 if (data.type() == typeid(identityRef_)) {
31 auto identityRef = boost::get<identityRef_>(data);
32 if (!identityRef.m_prefix) {
33 identityRef.m_prefix = set.m_path.m_nodes.front().m_prefix.value();
34 data = identityRef;
35 }
36 }
37 m_datastore.setLeaf(absolutePathFromCommand(set), data);
Václav Kubernát07204242018-06-04 18:12:09 +020038}
39
Václav Kubernátb6ff0b62018-08-30 16:14:53 +020040void Interpreter::operator()(const get_& get) const
41{
42 auto items = m_datastore.getItems(absolutePathFromCommand(get));
43 for (auto it : items) {
Václav Kubernát9b725992019-05-29 16:39:47 +020044 std::cout << it.first << " = " << leafDataToString(it.second) << std::endl;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +020045 }
46}
47
Václav Kubernát96344a12018-05-28 16:33:39 +020048void Interpreter::operator()(const cd_& cd) const
49{
50 m_parser.changeNode(cd.m_path);
51}
52
Václav Kubernátb61336d2018-05-28 17:35:03 +020053void Interpreter::operator()(const create_& create) const
54{
Václav Kubernátbe228622019-05-23 14:44:12 +020055 if (create.m_path.m_nodes.back().m_suffix.type() == typeid(listElement_))
56 m_datastore.createListInstance(absolutePathFromCommand(create));
57 else
58 m_datastore.createPresenceContainer(absolutePathFromCommand(create));
Václav Kubernátb61336d2018-05-28 17:35:03 +020059}
60
61void Interpreter::operator()(const delete_& delet) const
62{
Václav Kubernátf5f64f02019-03-19 17:15:47 +010063 if (delet.m_path.m_nodes.back().m_suffix.type() == typeid(container_))
64 m_datastore.deletePresenceContainer(absolutePathFromCommand(delet));
65 else
66 m_datastore.deleteListInstance(absolutePathFromCommand(delet));
Václav Kubernátb61336d2018-05-28 17:35:03 +020067}
68
Václav Kubernát11afac72018-07-18 14:59:53 +020069void Interpreter::operator()(const ls_& ls) const
70{
71 std::cout << "Possible nodes:" << std::endl;
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020072 auto recursion{Recursion::NonRecursive};
73 for (auto it : ls.m_options) {
74 if (it == LsOption::Recursive)
75 recursion = Recursion::Recursive;
76 }
Václav Kubernát11afac72018-07-18 14:59:53 +020077
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020078 for (const auto& it : m_parser.availableNodes(ls.m_path, recursion))
Václav Kubernát11afac72018-07-18 14:59:53 +020079 std::cout << it << std::endl;
80}
81
Václav Kubernát054cc992019-02-21 14:23:52 +010082struct commandLongHelpVisitor : boost::static_visitor<const char*> {
83 template <typename T>
84 auto constexpr operator()(boost::type<T>) const
85 {
86 return T::longHelp;
87 }
88};
89
90struct commandShortHelpVisitor : boost::static_visitor<const char*> {
91 template <typename T>
92 auto constexpr operator()(boost::type<T>) const
93 {
94 return T::shortHelp;
95 }
96};
97
98void Interpreter::operator()(const help_& help) const
99{
100 if (help.m_cmd)
101 std::cout << boost::apply_visitor(commandLongHelpVisitor(), help.m_cmd.get()) << std::endl;
102 else
103 boost::mpl::for_each<CommandTypes, boost::type<boost::mpl::_>>([](auto cmd) {
104 std::cout << commandShortHelpVisitor()(cmd) << std::endl;
105 });
106}
107
Václav Kubernát6415b822018-08-22 17:40:01 +0200108template <typename T>
109std::string Interpreter::absolutePathFromCommand(const T& command) const
110{
Václav Kubernát37171a12018-08-31 17:01:48 +0200111 if (command.m_path.m_scope == Scope::Absolute)
112 return "/" + pathToDataString(command.m_path);
113 else
114 return joinPaths(m_parser.currentNode(), pathToDataString(command.m_path));
Václav Kubernát6415b822018-08-22 17:40:01 +0200115}
116
Václav Kubernát5c75b252018-10-10 18:33:47 +0200117struct pathToStringVisitor : boost::static_visitor<std::string> {
118 std::string operator()(const schemaPath_& path) const
119 {
120 return pathToSchemaString(path);
121 }
122 std::string operator()(const dataPath_& path) const
123 {
124 return pathToDataString(path);
125 }
126};
127
128struct getPathScopeVisitor : boost::static_visitor<Scope> {
129 template <typename T>
130 Scope operator()(const T& path) const
131 {
132 return path.m_scope;
133 }
134};
135
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200136std::string Interpreter::absolutePathFromCommand(const get_& get) const
137{
Václav Kubernát9456b5c2019-10-02 21:14:52 +0200138 using namespace std::string_literals;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200139 if (!get.m_path) {
140 return m_parser.currentNode();
Václav Kubernát5c75b252018-10-10 18:33:47 +0200141 }
142
143 const auto path = *get.m_path;
Václav Kubernát9456b5c2019-10-02 21:14:52 +0200144 if (path.type() == typeid(module_)) {
145 return "/"s + boost::get<module_>(path).m_name + ":*";
Václav Kubernát5c75b252018-10-10 18:33:47 +0200146
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200147 } else {
Václav Kubernát9456b5c2019-10-02 21:14:52 +0200148 auto actualPath = boost::get<boost::variant<dataPath_, schemaPath_>>(path);
149 std::string pathString = boost::apply_visitor(pathToStringVisitor(), actualPath);
150 auto pathScope{boost::apply_visitor(getPathScopeVisitor(), actualPath)};
151
152 if (pathScope == Scope::Absolute) {
153 return "/" + pathString;
154 } else {
155 return joinPaths(m_parser.currentNode(), pathString);
156 }
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200157 }
158}
159
Václav Kubernát6415b822018-08-22 17:40:01 +0200160Interpreter::Interpreter(Parser& parser, DatastoreAccess& datastore)
Václav Kubernát812ee282018-08-30 17:10:03 +0200161 : m_parser(parser)
162 , m_datastore(datastore)
Václav Kubernát96344a12018-05-28 16:33:39 +0200163{
164}