blob: 634a19001b6775c82e2f9cc813206cb9cdc2ab7d [file] [log] [blame]
Václav Kubernát24df80e2018-06-06 15:18:03 +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#pragma once
9
Václav Kubernát57272422019-02-08 12:48:24 +010010#include <boost/mpl/vector.hpp>
Václav Kubernát24df80e2018-06-06 15:18:03 +020011#include "ast_path.hpp"
Václav Kubernát627f6152018-08-29 13:23:56 +020012#include "ast_values.hpp"
Václav Kubernát24df80e2018-06-06 15:18:03 +020013
14namespace x3 = boost::spirit::x3;
15namespace ascii = boost::spirit::x3::ascii;
16
17using ascii::space;
18using x3::_attr;
19using x3::alnum;
20using x3::alpha;
21using x3::char_;
Václav Kubernátebca2552018-06-08 19:06:02 +020022using x3::double_;
Václav Kubernát24df80e2018-06-06 15:18:03 +020023using x3::expect;
Václav Kubernátebca2552018-06-08 19:06:02 +020024using x3::int_;
Václav Kubernát24df80e2018-06-06 15:18:03 +020025using x3::lexeme;
26using x3::lit;
Václav Kubernátebca2552018-06-08 19:06:02 +020027using x3::uint_;
Václav Kubernát24df80e2018-06-06 15:18:03 +020028
29struct parser_context_tag;
30
31using keyValue_ = std::pair<std::string, std::string>;
32
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020033enum class LsOption {
34 Recursive
35};
36
Václav Kubernát6d791432018-10-25 16:00:35 +020037struct discard_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010038 static constexpr auto name = "discard";
Václav Kubernát054cc992019-02-21 14:23:52 +010039 static constexpr auto shortHelp = "discard - Discard current changes.";
40 static constexpr auto longHelp = R"(
41 discard
42
43 Discards current changes. Accepts no arguments.
44
45 Usage:
46 /> discard)";
Václav Kubernát6d791432018-10-25 16:00:35 +020047 bool operator==(const discard_& b) const;
48};
49
Václav Kubernát11afac72018-07-18 14:59:53 +020050struct ls_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010051 static constexpr auto name = "ls";
Václav Kubernát054cc992019-02-21 14:23:52 +010052 static constexpr auto shortHelp = "ls - List available nodes.";
53 static constexpr auto longHelp = R"(
54 ls [--recursive] [path]
55
56 Lists available nodes in the current directory. Optionally
57 accepts a path argument. Accepts both schema paths and data
58 paths. Path starting with a forward slash means an absolute
59 path.
60
61 Usage:
62 /> ls
63 /> ls --recursive module:node
64 /> ls /module:node)";
Václav Kubernát11afac72018-07-18 14:59:53 +020065 bool operator==(const ls_& b) const;
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020066 std::vector<LsOption> m_options;
Václav Kubernát5c75b252018-10-10 18:33:47 +020067 boost::optional<boost::variant<dataPath_, schemaPath_>> m_path;
Václav Kubernát11afac72018-07-18 14:59:53 +020068};
69
Václav Kubernát24df80e2018-06-06 15:18:03 +020070struct cd_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010071 static constexpr auto name = "cd";
Václav Kubernát054cc992019-02-21 14:23:52 +010072 static constexpr auto shortHelp = "cd - Enter a different node.";
73 static constexpr auto longHelp = R"(
74 cd path
75
76 Enters a node specified by path. Only accepts data paths.
77
78 Usage:
79 /> cd /module:node/node2
80 /> cd ..)";
Václav Kubernát24df80e2018-06-06 15:18:03 +020081 bool operator==(const cd_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +020082 dataPath_ m_path;
Václav Kubernát24df80e2018-06-06 15:18:03 +020083};
84
85struct create_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010086 static constexpr auto name = "create";
Václav Kubernát054cc992019-02-21 14:23:52 +010087 static constexpr auto shortHelp = "create - Create a presence container.";
88 static constexpr auto longHelp = R"(
89 create path_to_presence_container
90
91 Creates a presence container specified by a path.
92
93 Usage:
94 /> create /module:pContainer)";
Václav Kubernát24df80e2018-06-06 15:18:03 +020095 bool operator==(const create_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +020096 dataPath_ m_path;
Václav Kubernát24df80e2018-06-06 15:18:03 +020097};
98
99struct delete_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100100 static constexpr auto name = "delete";
Václav Kubernát054cc992019-02-21 14:23:52 +0100101 static constexpr auto shortHelp = "delete - Delete a presence container.";
102 static constexpr auto longHelp = R"(
103 delete path_to_presence_container
104
105 Delete a presence container specified by a path.
106
107 Usage:
108 /> delete /module:pContainer)";
Václav Kubernát24df80e2018-06-06 15:18:03 +0200109 bool operator==(const delete_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200110 dataPath_ m_path;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200111};
112
113struct set_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100114 static constexpr auto name = "set";
Václav Kubernát054cc992019-02-21 14:23:52 +0100115 static constexpr auto shortHelp = "set - Change value of a leaf.";
116 static constexpr auto longHelp = R"(
117 set path_to_leaf value
118
119 Changes the leaf specified by path to value.
120
121 Usage:
122 /> set /module:leaf 123
123 /> set /module:leaf abc)";
Václav Kubernát24df80e2018-06-06 15:18:03 +0200124 bool operator==(const set_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200125 dataPath_ m_path;
Václav Kubernátebca2552018-06-08 19:06:02 +0200126 leaf_data_ m_data;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200127};
128
Václav Kubernát812ee282018-08-30 17:10:03 +0200129struct commit_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100130 static constexpr auto name = "commit";
Václav Kubernát054cc992019-02-21 14:23:52 +0100131 static constexpr auto shortHelp = "commit - Commit current changes.";
132 static constexpr auto longHelp = R"(
133 commit
134
135 Commits the current changes. Accepts no arguments.
136
137 Usage:
138 /> commit)";
Václav Kubernát812ee282018-08-30 17:10:03 +0200139 bool operator==(const set_& b) const;
140};
141
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200142struct get_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100143 static constexpr auto name = "get";
Václav Kubernát054cc992019-02-21 14:23:52 +0100144 static constexpr auto shortHelp = "get - Retrieve configuration from the server.";
145 static constexpr auto longHelp = R"(
146 get [path]
147
148 Retrieves configuration of the current node. Works recursively.
149 Optionally takes an argument specifying a path, the output will,
150 as if the user was in that node.
151
152 Usage:
153 /> get
154 /> get /module:path)";
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200155 bool operator==(const get_& b) const;
Václav Kubernát5c75b252018-10-10 18:33:47 +0200156 boost::optional<boost::variant<dataPath_, schemaPath_>> m_path;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200157};
Václav Kubernát812ee282018-08-30 17:10:03 +0200158
Václav Kubernát054cc992019-02-21 14:23:52 +0100159struct help_;
160using CommandTypes = boost::mpl::vector<discard_, ls_, cd_, create_, delete_, set_, commit_, get_, help_>;
161struct help_ : x3::position_tagged {
162 static constexpr auto name = "help";
163 static constexpr auto shortHelp = "help - Print help for commands.";
164 static constexpr auto longHelp = R"(
165 help [command_name]
166
167 Print help for command_name. If used without an argument,
168 print short help for all commands.
169
170 Usage:
171 /> help
172 /> help cd
173 /> help help)";
174 bool operator==(const help_& b) const;
175
176 // The help command has got one optional argument – a command name (type).
177 // All commands are saved in CommandTypes, so we could just use that, but
178 // that way, Spirit would be default constructing the command structs,
179 // which is undesirable, so firstly we use mpl::transform to wrap
180 // CommandTypes with boost::type:
181 using WrappedCommandTypes = boost::mpl::transform<CommandTypes, boost::type<boost::mpl::_>>::type;
182 // Next, we create a variant over the wrapped types:
183 using CommandTypesVariant = boost::make_variant_over<WrappedCommandTypes>::type;
184 // Finally, we wrap the variant with boost::optional:
185 boost::optional<CommandTypesVariant> m_cmd;
186};
187
Václav Kubernát57272422019-02-08 12:48:24 +0100188// TODO: The usage of MPL won't be necessary after std::variant support is added to Spirit
189// https://github.com/boostorg/spirit/issues/270
Václav Kubernát57272422019-02-08 12:48:24 +0100190using command_ = boost::make_variant_over<CommandTypes>::type;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200191
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200192BOOST_FUSION_ADAPT_STRUCT(ls_, m_options, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200193BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
194BOOST_FUSION_ADAPT_STRUCT(create_, m_path)
195BOOST_FUSION_ADAPT_STRUCT(delete_, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200196BOOST_FUSION_ADAPT_STRUCT(set_, m_path, m_data)
Václav Kubernátab538992019-03-06 15:30:50 +0100197BOOST_FUSION_ADAPT_STRUCT(enum_, m_value)
198BOOST_FUSION_ADAPT_STRUCT(binary_, m_value)
Václav Kubernát812ee282018-08-30 17:10:03 +0200199BOOST_FUSION_ADAPT_STRUCT(commit_)
Václav Kubernát054cc992019-02-21 14:23:52 +0100200BOOST_FUSION_ADAPT_STRUCT(help_, m_cmd)
Václav Kubernát6d791432018-10-25 16:00:35 +0200201BOOST_FUSION_ADAPT_STRUCT(discard_)
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200202BOOST_FUSION_ADAPT_STRUCT(get_, m_path)