blob: d9d52144552ab0add03ad5f342c86d10467f9938 [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át812ee282018-08-30 17:10:03 +020013void Interpreter::operator()(const commit_&) const
14{
15 m_datastore.commitChanges();
16}
17
Václav Kubernát6d791432018-10-25 16:00:35 +020018void Interpreter::operator()(const discard_&) const
19{
20 m_datastore.discardChanges();
21}
22
Václav Kubernát07204242018-06-04 18:12:09 +020023void Interpreter::operator()(const set_& set) const
24{
Václav Kubernáteeb38842019-03-20 19:46:05 +010025 auto data = set.m_data;
26
27 // If the user didn't supply a module prefix for identityref, we need to add it ourselves
28 if (data.type() == typeid(identityRef_)) {
29 auto identityRef = boost::get<identityRef_>(data);
30 if (!identityRef.m_prefix) {
31 identityRef.m_prefix = set.m_path.m_nodes.front().m_prefix.value();
32 data = identityRef;
33 }
34 }
35 m_datastore.setLeaf(absolutePathFromCommand(set), data);
Václav Kubernát07204242018-06-04 18:12:09 +020036}
37
Václav Kubernátb6ff0b62018-08-30 16:14:53 +020038void Interpreter::operator()(const get_& get) const
39{
40 auto items = m_datastore.getItems(absolutePathFromCommand(get));
41 for (auto it : items) {
Václav Kubernát9b725992019-05-29 16:39:47 +020042 std::cout << it.first << " = " << leafDataToString(it.second) << std::endl;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +020043 }
44}
45
Václav Kubernát96344a12018-05-28 16:33:39 +020046void Interpreter::operator()(const cd_& cd) const
47{
48 m_parser.changeNode(cd.m_path);
49}
50
Václav Kubernátb61336d2018-05-28 17:35:03 +020051void Interpreter::operator()(const create_& create) const
52{
Václav Kubernátbe228622019-05-23 14:44:12 +020053 if (create.m_path.m_nodes.back().m_suffix.type() == typeid(listElement_))
54 m_datastore.createListInstance(absolutePathFromCommand(create));
55 else
56 m_datastore.createPresenceContainer(absolutePathFromCommand(create));
Václav Kubernátb61336d2018-05-28 17:35:03 +020057}
58
59void Interpreter::operator()(const delete_& delet) const
60{
Václav Kubernátf5f64f02019-03-19 17:15:47 +010061 if (delet.m_path.m_nodes.back().m_suffix.type() == typeid(container_))
62 m_datastore.deletePresenceContainer(absolutePathFromCommand(delet));
63 else
64 m_datastore.deleteListInstance(absolutePathFromCommand(delet));
Václav Kubernátb61336d2018-05-28 17:35:03 +020065}
66
Václav Kubernát11afac72018-07-18 14:59:53 +020067void Interpreter::operator()(const ls_& ls) const
68{
69 std::cout << "Possible nodes:" << std::endl;
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020070 auto recursion{Recursion::NonRecursive};
71 for (auto it : ls.m_options) {
72 if (it == LsOption::Recursive)
73 recursion = Recursion::Recursive;
74 }
Václav Kubernát11afac72018-07-18 14:59:53 +020075
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020076 for (const auto& it : m_parser.availableNodes(ls.m_path, recursion))
Václav Kubernát11afac72018-07-18 14:59:53 +020077 std::cout << it << std::endl;
78}
79
Václav Kubernát054cc992019-02-21 14:23:52 +010080struct commandLongHelpVisitor : boost::static_visitor<const char*> {
81 template <typename T>
82 auto constexpr operator()(boost::type<T>) const
83 {
84 return T::longHelp;
85 }
86};
87
88struct commandShortHelpVisitor : boost::static_visitor<const char*> {
89 template <typename T>
90 auto constexpr operator()(boost::type<T>) const
91 {
92 return T::shortHelp;
93 }
94};
95
96void Interpreter::operator()(const help_& help) const
97{
98 if (help.m_cmd)
99 std::cout << boost::apply_visitor(commandLongHelpVisitor(), help.m_cmd.get()) << std::endl;
100 else
101 boost::mpl::for_each<CommandTypes, boost::type<boost::mpl::_>>([](auto cmd) {
102 std::cout << commandShortHelpVisitor()(cmd) << std::endl;
103 });
104}
105
Václav Kubernát6415b822018-08-22 17:40:01 +0200106template <typename T>
107std::string Interpreter::absolutePathFromCommand(const T& command) const
108{
Václav Kubernát37171a12018-08-31 17:01:48 +0200109 if (command.m_path.m_scope == Scope::Absolute)
110 return "/" + pathToDataString(command.m_path);
111 else
112 return joinPaths(m_parser.currentNode(), pathToDataString(command.m_path));
Václav Kubernát6415b822018-08-22 17:40:01 +0200113}
114
Václav Kubernát5c75b252018-10-10 18:33:47 +0200115struct pathToStringVisitor : boost::static_visitor<std::string> {
116 std::string operator()(const schemaPath_& path) const
117 {
118 return pathToSchemaString(path);
119 }
120 std::string operator()(const dataPath_& path) const
121 {
122 return pathToDataString(path);
123 }
124};
125
126struct getPathScopeVisitor : boost::static_visitor<Scope> {
127 template <typename T>
128 Scope operator()(const T& path) const
129 {
130 return path.m_scope;
131 }
132};
133
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200134std::string Interpreter::absolutePathFromCommand(const get_& get) const
135{
136 if (!get.m_path) {
137 return m_parser.currentNode();
Václav Kubernát5c75b252018-10-10 18:33:47 +0200138 }
139
140 const auto path = *get.m_path;
141 std::string pathString = boost::apply_visitor(pathToStringVisitor(), path);
142 auto pathScope{boost::apply_visitor(getPathScopeVisitor(), path)};
143
144 if (pathScope == Scope::Absolute) {
145 return "/" + pathString;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200146 } else {
Václav Kubernát5c75b252018-10-10 18:33:47 +0200147 return joinPaths(m_parser.currentNode(), pathString);
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200148 }
149}
150
Václav Kubernát6415b822018-08-22 17:40:01 +0200151Interpreter::Interpreter(Parser& parser, DatastoreAccess& datastore)
Václav Kubernát812ee282018-08-30 17:10:03 +0200152 : m_parser(parser)
153 , m_datastore(datastore)
Václav Kubernát96344a12018-05-28 16:33:39 +0200154{
155}