3232#include " RemoteCommandHandler.h"
3333#include < vector>
3434#include < map>
35+ #include < functional>
3536
3637/* * Handle command of server side application
3738 *
@@ -56,9 +57,9 @@ class RemoteCommandHandlerTemplate : public IRemoteCommandHandler
5657 *
5758 * @return the command execution status, @see CommandStatus
5859 */
59- typedef CommandStatus (CommandParser::* RemoteCommandParser)( const IRemoteCommand&
60- remoteCommand ,
61- std::string& strResult) ;
60+ using RemoteCommandParser = std::function<CommandStatus(CommandParser&,
61+ const IRemoteCommand& ,
62+ std::string&)> ;
6263
6364 /* * Parser item definition */
6465 class RemoteCommandParserItem
@@ -119,7 +120,7 @@ class RemoteCommandHandlerTemplate : public IRemoteCommandHandler
119120 return false ;
120121 }
121122
122- switch ((commandParser.* mParser )( remoteCommand, result)) {
123+ switch (mParser (commandParser, remoteCommand, result)) {
123124 case EDone:
124125 result = " Done" ;
125126 // Fall through intentionally
@@ -158,9 +159,22 @@ class RemoteCommandHandlerTemplate : public IRemoteCommandHandler
158159 * @param remoteCommandParserItems supported command parser items
159160 */
160161 RemoteCommandHandlerTemplate (CommandParser& commandParser,
161- const RemoteCommandParserItems& remoteCommandParserItems) :
162+ RemoteCommandParserItems& remoteCommandParserItems) :
162163 _commandParser (commandParser), _remoteCommandParserItems(remoteCommandParserItems)
163164 {
165+ /* Add the help command and specialize the help function
166+ * to match RemoteCommandParser prototype
167+ */
168+ _remoteCommandParserItems.emplace (
169+ " help" ,
170+ RemoteCommandParserItem (
171+ std::bind (&RemoteCommandHandlerTemplate<CommandParser>::help,
172+ this ,
173+ std::ref (_remoteCommandParserItems),
174+ std::placeholders::_1,
175+ std::placeholders::_2,
176+ std::placeholders::_3),
177+ 0 , " " , " Show commands description and usage" ));
164178 }
165179
166180private:
@@ -181,14 +195,6 @@ class RemoteCommandHandlerTemplate : public IRemoteCommandHandler
181195 return remoteCommandParserItem.parse (_commandParser, remoteCommand, result);
182196 }
183197 catch (const std::out_of_range&) {
184-
185- if (remoteCommand.getCommand () == helpCommand) {
186-
187- help (result);
188-
189- return true ;
190- }
191-
192198 // Not found
193199 result = " Command not found!\n Use \" help\" to show available commands" ;
194200
@@ -197,16 +203,25 @@ class RemoteCommandHandlerTemplate : public IRemoteCommandHandler
197203 }
198204
199205 /* * Format help display
206+ * This method has to be able to match RemoteCommandParser prototype after partial
207+ * specialization to be called like any other command. Thus, it takes a
208+ * RemoteCommandParserItems in first argument and RemoteCommandParser arguments follows.
200209 *
210+ * @param[in] items, command description container
201211 * @param result the formatted help string
212+ *
213+ * @return ESucceeded command status
202214 */
203- void help (std::string& result)
215+ CommandStatus help (const RemoteCommandParserItems& items,
216+ CommandParser&,
217+ const IRemoteCommand&,
218+ std::string& result)
204219 {
205220 struct Help { std::string usage; std::string description; };
206- std::vector<Help> helps{ { helpCommand, helpCommandDescription } } ;
207- size_t maxUsage = helpCommand. length () ;
221+ std::vector<Help> helps;
222+ size_t maxUsage = 0 ;
208223
209- for (auto & item : _remoteCommandParserItems ) {
224+ for (auto & item : items ) {
210225 std::string usage = item.first + ' ' + item.second .getHelp ();
211226 helps.push_back ({ usage, item.second .getDescription () });
212227 maxUsage = std::max (maxUsage, usage.length ());
@@ -216,24 +231,12 @@ class RemoteCommandHandlerTemplate : public IRemoteCommandHandler
216231 help.usage .resize (maxUsage, ' ' );
217232 result += help.usage + " => " + help.description + ' \n ' ;
218233 }
234+ return CommandStatus::ESucceeded;
219235 }
220236
221- /* * Help command name */
222- static const std::string helpCommand;
223-
224- /* * Help command description */
225- static const std::string helpCommandDescription;
226-
227237 /* * Command parser used during command during command handling */
228238 CommandParser& _commandParser;
229239
230240 /* * Remote command parser map */
231- const RemoteCommandParserItems& _remoteCommandParserItems;
241+ RemoteCommandParserItems& _remoteCommandParserItems;
232242};
233-
234- template <typename CommandParser>
235- const std::string RemoteCommandHandlerTemplate<CommandParser>::helpCommand = " help" ;
236-
237- template <typename CommandParser>
238- const std::string RemoteCommandHandlerTemplate<CommandParser>::helpCommandDescription =
239- " Show commands description and usage" ;
0 commit comments