hyperledger/iroha
Iroha - A simple, decentralized ledger http://iroha.tech
interactive_common_cli.hpp
Go to the documentation of this file.
1 
6 #ifndef IROHA_CLI_INTERACTIVE_COMMON_CLI_HPP
7 #define IROHA_CLI_INTERACTIVE_COMMON_CLI_HPP
8 
9 #include <algorithm>
10 #include <ciso646>
11 #include <iostream>
12 #include <memory>
13 #include <string>
14 #include <unordered_map>
15 #include <vector>
16 
17 #include <boost/optional.hpp>
18 
19 namespace parser {
20  boost::optional<std::string> parseFirstCommand(std::string line);
21 }
22 
23 namespace iroha_cli {
24  namespace interactive {
25 
29  enum MenuContext {
38  };
39 
43  struct ParamData {
47  std::string message;
48 
52  std::string cache;
53  };
54 
55  // Description of parameters
56  using ParamsDescription = std::vector<ParamData>;
57  // map for command - command description relationship
58  using DescriptionMap = std::unordered_map<std::string, std::string>;
59  // Points in a menu
60  using MenuPoints = std::vector<std::string>;
61  // map for command - ParamsDescription relationship
62  using ParamsMap = std::unordered_map<std::string, ParamsDescription>;
63 
64  // ------ Common commands short name ---------
65  const std::string SAVE_CODE = "save";
66  const std::string SEND_CODE = "send";
67  const std::string BACK_CODE = "b";
68 
74 
82  ParamsMap getCommonParamsMap(const std::string &default_ip,
83  int default_port);
84 
91  const std::vector<std::string> &params);
92 
96  void handleEmptyCommand();
97 
102  void handleUnknownCommand(std::string &command);
103 
108  void addBackOption(MenuPoints &menu);
109 
115  bool isBackOption(std::string line);
116 
120  void printEnd();
121 
127  void printCommandParameters(std::string &command,
128  const ParamsDescription &parameters);
129 
135  void printMenu(const std::string &message, MenuPoints menu_points);
136 
142  boost::optional<std::string> promptString(const std::string &message);
143 
149  boost::optional<std::string> promptString(const ParamData &param);
150 
162  boost::optional<std::vector<std::string>> parseParams(
163  std::string line, std::string command_name, ParamsMap &params_map);
164 
171  size_t addMenuPoint(std::vector<std::string> &menu_points,
172  const std::string &description,
173  const std::string &command_short_name);
174 
183  template <typename K, typename V>
184  std::size_t getNextIndex(std::unordered_map<K, V> parsers_map) {
185  return parsers_map.size() == 0 ? 1 : parsers_map.size();
186  }
187 
197  template <typename K, typename V>
198  boost::optional<V &> findInHandlerMap(
199  K command_name, std::unordered_map<K, V> &params_map) {
200  auto it = params_map.find(command_name);
201  if (it == params_map.end()) {
202  // Command not found, report error
203  handleUnknownCommand(command_name);
204  return boost::none;
205  }
206  return it->second;
207  }
208 
214  boost::optional<std::pair<std::string, uint16_t>> parseIrohaPeerParams(
215  std::vector<std::string> params,
216  const std::string &default_ip,
217  int default_port);
218 
233  template <typename T, typename V, typename C>
234  boost::optional<T> handleParse(
235  C class_pointer,
236  std::string &line,
237  std::unordered_map<std::string, V> &parsers_map,
238  ParamsMap &params_map) {
239  auto raw_command = parser::parseFirstCommand(line);
240  if (not raw_command) {
242  return boost::none;
243  }
244  auto command_name = raw_command.value();
245  auto parser = findInHandlerMap(command_name, parsers_map);
246  if (not parser) {
247  std::cout << "Parser for command not found" << std::endl;
248  return boost::none;
249  }
250  auto params = parseParams(line, command_name, params_map);
251  if (not params) {
252  std::cout << "Parse params returned no value" << std::endl;
253  return boost::none;
254  }
255  return (class_pointer->*parser.value())(params.value());
256  }
257 
267  template <typename V>
268  void addCliCommand(MenuPoints &menu_points,
269  std::unordered_map<std::string, V> &parsers_map,
270  const std::string &command_name,
271  const std::string &command_description,
272  V parser) {
273  // Add menu point and get the index in menu of current command
274  auto index = std::to_string(
275  addMenuPoint(menu_points, command_description, command_name));
276  // Add parser for this command
277  parsers_map[index] = parser;
278  parsers_map[command_name] = parser;
279  }
280 
290  template <typename V>
291  MenuPoints formMenu(std::unordered_map<std::string, V> &parsers_map,
292  ParamsMap &paramsMap,
293  const DescriptionMap descriptionMap) {
294  // Add menu point and get the index in menu of current command
295  MenuPoints menu_points;
296  std::for_each(descriptionMap.begin(),
297  descriptionMap.end(),
298  [&parsers_map, &menu_points, &paramsMap](auto val) {
299  auto command_name = val.first;
300  auto command_description = val.second;
301 
302  auto index = std::to_string(addMenuPoint(
303  menu_points, command_description, command_name));
304  parsers_map[index] = parsers_map.at(command_name);
305  ;
306  paramsMap[index] = paramsMap.at(command_name);
307  });
308  return menu_points;
309  }
310 
311  } // namespace interactive
312 } // namespace iroha_cli
313 
314 #endif // IROHA_CLI_INTERACTIVE_COMMON_CLI_HPP
boost::optional< std::string > promptString(const std::string &message)
Definition: interactive_common_cli.cpp:80
Definition: client.cpp:16
std::string to_string(const Collection &collection, Lambda transform)
Definition: logger.hpp:124
DescriptionMap getCommonDescriptionMap()
Definition: interactive_common_cli.cpp:15
MenuContext
Definition: interactive_common_cli.hpp:29
const std::string SAVE_CODE
Definition: interactive_common_cli.hpp:65
std::vector< ParamData > ParamsDescription
Definition: interactive_common_cli.hpp:56
const std::string BACK_CODE
Definition: interactive_common_cli.hpp:67
void handleUnknownCommand(std::string &command)
Definition: interactive_common_cli.cpp:51
Definition: interactive_common_cli.hpp:37
void printMenu(const std::string &message, MenuPoints menu_points)
Definition: interactive_common_cli.cpp:73
std::vector< std::string > MenuPoints
Definition: interactive_common_cli.hpp:60
void printCommandParameters(std::string &command, const ParamsDescription &parameters)
Definition: interactive_common_cli.cpp:64
size_t addMenuPoint(std::vector< std::string > &menu_points, const std::string &description, const std::string &command_short_name)
Definition: interactive_common_cli.cpp:161
Definition: interactive_common_cli.hpp:43
std::size_t getNextIndex(std::unordered_map< K, V > parsers_map)
Definition: interactive_common_cli.hpp:184
boost::optional< std::vector< std::string > > parseParams(std::string line, std::string command_name, ParamsMap &params_map)
Definition: interactive_common_cli.cpp:117
boost::optional< std::string > parseFirstCommand(std::string line)
Definition: parser.cpp:20
std::unordered_map< std::string, ParamsDescription > ParamsMap
Definition: interactive_common_cli.hpp:62
boost::optional< T > handleParse(C class_pointer, std::string &line, std::unordered_map< std::string, V > &parsers_map, ParamsMap &params_map)
Definition: interactive_common_cli.hpp:234
void printEnd()
Definition: interactive_common_cli.cpp:98
void addBackOption(MenuPoints &menu)
Definition: interactive_common_cli.cpp:55
std::string cache
Definition: interactive_common_cli.hpp:52
boost::optional< std::pair< std::string, uint16_t > > parseIrohaPeerParams(std::vector< std::string > params, const std::string &default_ip, int default_port)
Definition: interactive_common_cli.cpp:102
ParamsMap getCommonParamsMap(const std::string &default_ip, int default_port)
Definition: interactive_common_cli.cpp:24
std::unordered_map< std::string, std::string > DescriptionMap
Definition: interactive_common_cli.hpp:58
const std::string SEND_CODE
Definition: interactive_common_cli.hpp:66
ParamsDescription makeParamsDescription(const std::vector< std::string > &params)
Definition: interactive_common_cli.cpp:36
MenuPoints formMenu(std::unordered_map< std::string, V > &parsers_map, ParamsMap &paramsMap, const DescriptionMap descriptionMap)
Definition: interactive_common_cli.hpp:291
Definition: interactive_common_cli.hpp:19
void addCliCommand(MenuPoints &menu_points, std::unordered_map< std::string, V > &parsers_map, const std::string &command_name, const std::string &command_description, V parser)
Definition: interactive_common_cli.hpp:268
boost::optional< V & > findInHandlerMap(K command_name, std::unordered_map< K, V > &params_map)
Definition: interactive_common_cli.hpp:198
void handleEmptyCommand()
Definition: interactive_common_cli.cpp:47
Definition: interactive_common_cli.hpp:33
std::string message
Definition: interactive_common_cli.hpp:47
bool isBackOption(std::string line)
Definition: interactive_common_cli.cpp:59