LCOV - code coverage report
Current view: top level - iroha-cli/interactive - interactive_common_cli.hpp (source / functions) Hit Total Coverage
Test: cleared_cor.info Lines: 0 38 0.0 %
Date: 2019-03-07 14:46:43 Functions: 0 38 0.0 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Soramitsu Co., Ltd. All Rights Reserved.
       3             :  * SPDX-License-Identifier: Apache-2.0
       4             :  */
       5             : 
       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             : 
      26             :     /**
      27             :      * Parsing menu context, used to identify the context of parsing
      28             :      */
      29             :     enum MenuContext {
      30             :       /**
      31             :        * Main menu context, used to print all commands/queries
      32             :        */
      33             :       MAIN,
      34             :       /**
      35             :        * Result menu, used for send, save tx/query
      36             :        */
      37             :       RESULT
      38             :     };
      39             : 
      40             :     /**
      41             :      * Data structure for parameter data
      42             :      */
      43             :     struct ParamData {
      44             :       /**
      45             :        * Message to display when prompting for user input
      46             :        */
      47             :       std::string message;
      48             : 
      49             :       /**
      50             :        * Cached user input for the parameter or the default value
      51             :        */
      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             : 
      69             :     /**
      70             :      * Return mapping of Command_name to Command description
      71             :      * @return DesciptionMap for common commands
      72             :      */
      73             :     DescriptionMap getCommonDescriptionMap();
      74             : 
      75             :     /**
      76             :      * Return mapping of Command_name to parameters descriptions
      77             :      * @param default_ip - default hostname or IP to be used when connecting to
      78             :      * irohad
      79             :      * @param default_port - default port to be used when connecting to irohad
      80             :      * @return ParamsMap with parameters of common commands
      81             :      */
      82             :     ParamsMap getCommonParamsMap(const std::string &default_ip,
      83             :                                  int default_port);
      84             : 
      85             :     /**
      86             :      * Creates parameters descriptions with empty default/cache values
      87             :      * @param params - parameters as a vector of prompt messages
      88             :      * @return ParamsDescription with parameter data
      89             :      */
      90             :     ParamsDescription makeParamsDescription(
      91             :         const std::vector<std::string> &params);
      92             : 
      93             :     /**
      94             :      * Handle error with empty command
      95             :      */
      96             :     void handleEmptyCommand();
      97             : 
      98             :     /**
      99             :      * Handle error of unknown command
     100             :      * @param command - name of unknown command
     101             :      */
     102             :     void handleUnknownCommand(std::string &command);
     103             : 
     104             :     /**
     105             :      * Add back option to menu
     106             :      * @param menu - menu to add the back option
     107             :      */
     108             :     void addBackOption(MenuPoints &menu);
     109             : 
     110             :     /**
     111             :      * Is line contains "Go Back" option
     112             :      * @param line to parse
     113             :      * @return true if line has command "go back"
     114             :      */
     115             :     bool isBackOption(std::string line);
     116             : 
     117             :     /**
     118             :      * Print end of session symbol
     119             :      */
     120             :     void printEnd();
     121             : 
     122             :     /**
     123             :      * Print help for cli command.
     124             :      * @param command - name of the cli command
     125             :      * @param parameters needed to run the command
     126             :      */
     127             :     void printCommandParameters(std::string &command,
     128             :                                 const ParamsDescription &parameters);
     129             : 
     130             :     /**
     131             :      * Pretty Print of menu
     132             :      * @param message - message to print before menu
     133             :      * @param menu_points - elements of the menu
     134             :      */
     135             :     void printMenu(const std::string &message, MenuPoints menu_points);
     136             : 
     137             :     /**
     138             :      * Get string input from user
     139             :      * @param message Message to ask user
     140             :      * @return nullopt if termintaing symbol, else user's input
     141             :      */
     142             :     boost::optional<std::string> promptString(const std::string &message);
     143             : 
     144             :     /**
     145             :      * Construct a prompt and get a string input from user
     146             :      * @param param Parameter to collect the input for
     147             :      * @return nullopt if termintaing symbol, else user's input
     148             :      */
     149             :     boost::optional<std::string> promptString(const ParamData &param);
     150             : 
     151             :     /**
     152             :      * Parse parameters in interactive and shortcuted mode.
     153             :      * Function run interactive mode if in line only the command name is passed.
     154             :      * Function will parse all needed parameters from line if the line with
     155             :      * commands is passed, it will print help if there are not enough parameters
     156             :      * in line.
     157             :      * @param line - cli line to parse
     158             :      * @param command_name - command name to print
     159             :      * @param notes - parameters needed to run the command
     160             :      * @return vector with needed parameters
     161             :      */
     162             :     boost::optional<std::vector<std::string>> parseParams(
     163             :         std::string line, std::string command_name, ParamsMap &params_map);
     164             : 
     165             :     /**
     166             :      * Add menu point to vector menu
     167             :      * @param menu_points to add new point
     168             :      * @param description of the command to add
     169             :      * @param command_short_name command short name
     170             :      */
     171             :     size_t addMenuPoint(std::vector<std::string> &menu_points,
     172             :                         const std::string &description,
     173             :                         const std::string &command_short_name);
     174             : 
     175             :     /**
     176             :      * Get next numerical index in the map.
     177             :      * Used to build menu
     178             :      * @tparam K - key type in map
     179             :      * @tparam V - value type in map
     180             :      * @param parsers_map - map to process
     181             :      * @return index for the next menu point
     182             :      */
     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             : 
     188             :     /**
     189             :      * Find in unordered map with error reporting.
     190             :      * Will print unkown command if key not found.
     191             :      * @tparam K key type
     192             :      * @tparam V value type
     193             :      * @param command_name - key to find in the map
     194             :      * @param params_map - map
     195             :      * @return nullopt if key not found, value if found
     196             :      */
     197             :     template <typename K, typename V>
     198             :     boost::optional<V &> findInHandlerMap(
     199             :         K command_name, std::unordered_map<K, V> &params_map) {
     200           0 :       auto it = params_map.find(command_name);
     201           0 :       if (it == params_map.end()) {
     202             :         // Command not found, report error
     203           0 :         handleUnknownCommand(command_name);
     204           0 :         return boost::none;
     205             :       }
     206           0 :       return it->second;
     207           0 :     }
     208             : 
     209             :     /**
     210             :      * Parse parameters related to Iroha Peer
     211             :      * @param params in format: vector of strings
     212             :      * @return pair if ip and port if formed right, nullopt otherwise
     213             :      */
     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             : 
     219             :     /**
     220             :      * Handle parsing routine:
     221             :      *  - find appropriate parser function for the command
     222             :      *  - get input from user for the command
     223             :      *  - trigger specific parser
     224             :      * @tparam T - expected return type of a parsing function
     225             :      * @tparam V - type of the parser function in parsers_map
     226             :      * @tparam C - class type of class_pointer
     227             :      * @param class_pointer - class pointer that holds parser functions
     228             :      * @param line - line to parse
     229             :      * @param parsers_map - map holding parser functions
     230             :      * @param params_map - map holding descriptions for command parameters
     231             :      * @return T if parsing successful, nullopt otherwise
     232             :      */
     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           0 :       auto raw_command = parser::parseFirstCommand(line);
     240           0 :       if (not raw_command) {
     241           0 :         handleEmptyCommand();
     242           0 :         return boost::none;
     243             :       }
     244           0 :       auto command_name = raw_command.value();
     245           0 :       auto parser = findInHandlerMap(command_name, parsers_map);
     246           0 :       if (not parser) {
     247           0 :         std::cout << "Parser for command not found" << std::endl;
     248           0 :         return boost::none;
     249             :       }
     250           0 :       auto params = parseParams(line, command_name, params_map);
     251           0 :       if (not params) {
     252           0 :         std::cout << "Parse params returned no value" << std::endl;
     253           0 :         return boost::none;
     254             :       }
     255           0 :       return (class_pointer->*parser.value())(params.value());
     256           0 :     }
     257             : 
     258             :     /**
     259             :      * Add new  cli command to menu points and menu handlers (parsers)
     260             :      * @tparam V type of parser functions in parsers_map
     261             :      * @param menu_points - menu to which points will be added
     262             :      * @param parsers_map - map holding specific parser functions
     263             :      * @param command_name - short command name
     264             :      * @param command_description - description for the command
     265             :      * @param parser - specific parser for current command
     266             :      */
     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           0 :       auto index = std::to_string(
     275           0 :           addMenuPoint(menu_points, command_description, command_name));
     276             :       // Add parser for this command
     277           0 :       parsers_map[index] = parser;
     278           0 :       parsers_map[command_name] = parser;
     279           0 :     }
     280             : 
     281             :     /**
     282             :      * Form menu points from given parameters and bind index of the command with
     283             :      * their parser and parameters
     284             :      * @tparam V - type of specific  parser functions in parsers_map
     285             :      * @param parsers_map - map holding specific parser functions
     286             :      * @param paramsMap - map holding descriptions for command parameters
     287             :      * @param descriptionMap - map holding description of a command
     288             :      * @return Formed menu points
     289             :      */
     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           0 :       MenuPoints menu_points;
     296           0 :       std::for_each(descriptionMap.begin(),
     297           0 :                     descriptionMap.end(),
     298             :                     [&parsers_map, &menu_points, &paramsMap](auto val) {
     299           0 :                       auto command_name = val.first;
     300           0 :                       auto command_description = val.second;
     301             : 
     302           0 :                       auto index = std::to_string(addMenuPoint(
     303           0 :                           menu_points, command_description, command_name));
     304           0 :                       parsers_map[index] = parsers_map.at(command_name);
     305             :                       ;
     306           0 :                       paramsMap[index] = paramsMap.at(command_name);
     307           0 :                     });
     308           0 :       return menu_points;
     309           0 :     }
     310             : 
     311             :   }  // namespace interactive
     312             : }  // namespace iroha_cli
     313             : 
     314             : #endif  // IROHA_CLI_INTERACTIVE_COMMON_CLI_HPP

Generated by: LCOV version 1.13