summaryrefslogtreecommitdiff
path: root/src/command/commandHandler.hpp
blob: 5a8636f27a4245c2159e54fd6bc85343425c2df3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#pragma once

#include "../core/session.hpp"
#include <any>
#include <functional>
#include "../misc/memory.hpp"
#include <netinet/in.h>
#include <string>
#include <vector>

class CCommandHandler {
  public:
	CCommandHandler();
	~CCommandHandler();

	struct SResult {
		std::string result;
		bool		good = false;
	};

	struct SParseResult {
		std::any data;
		bool	 good = false;
	};

	struct SCommand {
		bool												 requireAdmin = true;
		std::string											 name;
		std::function<SParseResult(const std::string &args)> parser;
		std::function<SResult(const std::any &parsed)>		 exe;
	};

	bool isCommand(const std::string &str) const;
	bool validCommand(const std::string &command) const;
	// return false if command struct is invalid
	bool	registerCommand(const SCommand &command);
	SResult newCommand(const std::string &command, const std::string &args, SP<CSession> session) const;
	void	handleCommand(std::string input, SP<CSession> user = nullptr) const;

	template <typename T>
	struct SMakeCommandArgs {
		std::string												   name;
		std::function<std::pair<T, bool>(const std::string &args)> parser;
		std::function<SResult(const T &parsed)>					   exe;
	};

	template <typename T>
	static SCommand makeCommand(SMakeCommandArgs<T> args) {
		return {
			.name	= std::move(args.name),
			.parser = [parser = std::move(args.parser)](const std::string &args) -> SParseResult {
				auto [data, good] = parser(args);
				return {.data = std::any(std::move(data)), .good = good};
			},
			.exe = [exe = std::move(args.exe)](const std::any &parsed) -> SResult {
				try {
					return exe(std::any_cast<const T &>(parsed));
				} catch (const std::bad_any_cast &) {
					return {.result = "Invalid data type", .good = false};
				}
			}
		};
	}

  private:
	SP<CCommandHandler::SCommand> getCommand(const std::string &command) const;
	SResult									   exeCommand(const SP<SCommand> command, const std::string &args) const;

	std::vector<SP<SCommand>> m_vCommands;
};
inline UP<CCommandHandler> g_pCommandHandler;