blob: eca4879e5f4089fa446440be39139fe2d4644438 [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átb61336d2018-05-28 17:35:03 +02009#include <iostream>
Václav Kubernát6415b822018-08-22 17:40:01 +020010#include "datastore_access.hpp"
Václav Kubernát96344a12018-05-28 16:33:39 +020011#include "interpreter.hpp"
12
Václav Kubernátebca2552018-06-08 19:06:02 +020013struct leafDataToString : boost::static_visitor<std::string> {
14 std::string operator()(const enum_& data) const
15 {
16 return data.m_value;
17 }
Václav Kubernátab538992019-03-06 15:30:50 +010018
19 std::string operator()(const binary_& data) const
20 {
21 return data.m_value;
22 }
23
Václav Kubernáteeb38842019-03-20 19:46:05 +010024 std::string operator()(const identityRef_& data) const
25 {
26 return data.m_value;
27 }
28
Václav Kubernátebca2552018-06-08 19:06:02 +020029 template <typename T>
30 std::string operator()(const T& data) const
31 {
32 std::stringstream stream;
33 stream << data;
34 return stream.str();
35 }
36};
37
Václav Kubernát812ee282018-08-30 17:10:03 +020038void Interpreter::operator()(const commit_&) const
39{
40 m_datastore.commitChanges();
41}
42
Václav Kubernát6d791432018-10-25 16:00:35 +020043void Interpreter::operator()(const discard_&) const
44{
45 m_datastore.discardChanges();
46}
47
Václav Kubernát07204242018-06-04 18:12:09 +020048void Interpreter::operator()(const set_& set) const
49{
Václav Kubernáteeb38842019-03-20 19:46:05 +010050 auto data = set.m_data;
51
52 // If the user didn't supply a module prefix for identityref, we need to add it ourselves
53 if (data.type() == typeid(identityRef_)) {
54 auto identityRef = boost::get<identityRef_>(data);
55 if (!identityRef.m_prefix) {
56 identityRef.m_prefix = set.m_path.m_nodes.front().m_prefix.value();
57 data = identityRef;
58 }
59 }
60 m_datastore.setLeaf(absolutePathFromCommand(set), data);
Václav Kubernát07204242018-06-04 18:12:09 +020061}
62
Václav Kubernátb6ff0b62018-08-30 16:14:53 +020063void Interpreter::operator()(const get_& get) const
64{
65 auto items = m_datastore.getItems(absolutePathFromCommand(get));
66 for (auto it : items) {
67 std::cout << it.first << " = " << boost::apply_visitor(leafDataToString(), it.second) << std::endl;
68 }
69}
70
Václav Kubernát96344a12018-05-28 16:33:39 +020071void Interpreter::operator()(const cd_& cd) const
72{
73 m_parser.changeNode(cd.m_path);
74}
75
Václav Kubernátb61336d2018-05-28 17:35:03 +020076void Interpreter::operator()(const create_& create) const
77{
Václav Kubernátbe228622019-05-23 14:44:12 +020078 if (create.m_path.m_nodes.back().m_suffix.type() == typeid(listElement_))
79 m_datastore.createListInstance(absolutePathFromCommand(create));
80 else
81 m_datastore.createPresenceContainer(absolutePathFromCommand(create));
Václav Kubernátb61336d2018-05-28 17:35:03 +020082}
83
84void Interpreter::operator()(const delete_& delet) const
85{
Václav Kubernátf5f64f02019-03-19 17:15:47 +010086 if (delet.m_path.m_nodes.back().m_suffix.type() == typeid(container_))
87 m_datastore.deletePresenceContainer(absolutePathFromCommand(delet));
88 else
89 m_datastore.deleteListInstance(absolutePathFromCommand(delet));
Václav Kubernátb61336d2018-05-28 17:35:03 +020090}
91
Václav Kubernát11afac72018-07-18 14:59:53 +020092void Interpreter::operator()(const ls_& ls) const
93{
94 std::cout << "Possible nodes:" << std::endl;
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020095 auto recursion{Recursion::NonRecursive};
96 for (auto it : ls.m_options) {
97 if (it == LsOption::Recursive)
98 recursion = Recursion::Recursive;
99 }
Václav Kubernát11afac72018-07-18 14:59:53 +0200100
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200101 for (const auto& it : m_parser.availableNodes(ls.m_path, recursion))
Václav Kubernát11afac72018-07-18 14:59:53 +0200102 std::cout << it << std::endl;
103}
104
Václav Kubernát054cc992019-02-21 14:23:52 +0100105struct commandLongHelpVisitor : boost::static_visitor<const char*> {
106 template <typename T>
107 auto constexpr operator()(boost::type<T>) const
108 {
109 return T::longHelp;
110 }
111};
112
113struct commandShortHelpVisitor : boost::static_visitor<const char*> {
114 template <typename T>
115 auto constexpr operator()(boost::type<T>) const
116 {
117 return T::shortHelp;
118 }
119};
120
121void Interpreter::operator()(const help_& help) const
122{
123 if (help.m_cmd)
124 std::cout << boost::apply_visitor(commandLongHelpVisitor(), help.m_cmd.get()) << std::endl;
125 else
126 boost::mpl::for_each<CommandTypes, boost::type<boost::mpl::_>>([](auto cmd) {
127 std::cout << commandShortHelpVisitor()(cmd) << std::endl;
128 });
129}
130
Václav Kubernát6415b822018-08-22 17:40:01 +0200131template <typename T>
132std::string Interpreter::absolutePathFromCommand(const T& command) const
133{
Václav Kubernát37171a12018-08-31 17:01:48 +0200134 if (command.m_path.m_scope == Scope::Absolute)
135 return "/" + pathToDataString(command.m_path);
136 else
137 return joinPaths(m_parser.currentNode(), pathToDataString(command.m_path));
Václav Kubernát6415b822018-08-22 17:40:01 +0200138}
139
Václav Kubernát5c75b252018-10-10 18:33:47 +0200140struct pathToStringVisitor : boost::static_visitor<std::string> {
141 std::string operator()(const schemaPath_& path) const
142 {
143 return pathToSchemaString(path);
144 }
145 std::string operator()(const dataPath_& path) const
146 {
147 return pathToDataString(path);
148 }
149};
150
151struct getPathScopeVisitor : boost::static_visitor<Scope> {
152 template <typename T>
153 Scope operator()(const T& path) const
154 {
155 return path.m_scope;
156 }
157};
158
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200159std::string Interpreter::absolutePathFromCommand(const get_& get) const
160{
161 if (!get.m_path) {
162 return m_parser.currentNode();
Václav Kubernát5c75b252018-10-10 18:33:47 +0200163 }
164
165 const auto path = *get.m_path;
166 std::string pathString = boost::apply_visitor(pathToStringVisitor(), path);
167 auto pathScope{boost::apply_visitor(getPathScopeVisitor(), path)};
168
169 if (pathScope == Scope::Absolute) {
170 return "/" + pathString;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200171 } else {
Václav Kubernát5c75b252018-10-10 18:33:47 +0200172 return joinPaths(m_parser.currentNode(), pathString);
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200173 }
174}
175
Václav Kubernát6415b822018-08-22 17:40:01 +0200176Interpreter::Interpreter(Parser& parser, DatastoreAccess& datastore)
Václav Kubernát812ee282018-08-30 17:10:03 +0200177 : m_parser(parser)
178 , m_datastore(datastore)
Václav Kubernát96344a12018-05-28 16:33:39 +0200179{
180}