TrinityCore
ChatCommandHelpers.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITY_CHATCOMMANDHELPERS_H
19#define TRINITY_CHATCOMMANDHELPERS_H
20
21#include "Define.h"
22#include "Language.h"
23#include "Optional.h"
24#include "StringFormat.h"
25#include <fmt/printf.h>
26#include <string>
27#include <string_view>
28#include <type_traits>
29#include <variant>
30
31class ChatHandler;
32
34{
35 /***************** HELPERS *************************\
36 |* These really aren't for outside use... *|
37 \***************************************************/
38
39 static constexpr char COMMAND_DELIMITER = ' ';
40
41 template <typename T, typename = void>
42 struct tag_base
43 {
44 using type = T;
45 };
46
47 template <typename T>
48 using tag_base_t = typename tag_base<T>::type;
49
51 explicit operator bool() { return !token.empty(); }
52 std::string_view token;
53 std::string_view tail;
54 };
55
56 inline TokenizeResult tokenize(std::string_view args)
57 {
58 TokenizeResult result;
59 if (size_t delimPos = args.find(COMMAND_DELIMITER); delimPos != std::string_view::npos)
60 {
61 result.token = args.substr(0, delimPos);
62 if (size_t tailPos = args.find_first_not_of(COMMAND_DELIMITER, delimPos); tailPos != std::string_view::npos)
63 result.tail = args.substr(tailPos);
64 }
65 else
66 result.token = args;
67
68 return result;
69 }
70
71 template <typename T, typename... Ts>
73 {
74 static constexpr bool value = (std::is_assignable_v<T&, Ts> && ...);
75 };
76
77 template <typename... Ts>
78 struct are_all_assignable<void, Ts...>
79 {
80 static constexpr bool value = false;
81 };
82
83 template <std::size_t index, typename T1, typename... Ts>
84 struct get_nth : get_nth<index-1, Ts...> { };
85
86 template <typename T1, typename... Ts>
87 struct get_nth<0, T1, Ts...>
88 {
89 using type = T1;
90 };
91
92 template <std::size_t index, typename... Ts>
93 using get_nth_t = typename get_nth<index, Ts...>::type;
94
95 // this essentially models std::optional<std::string_view>, except it can also hold an error message
96 // it has std::string_view's bool conversion and dereference operators
97 //
98 // monostate <-> unspecified error, typically end-of-string reached or parsing failed
99 // std::string <-> specified error, typically character-not-found or invalid item link
100 // std::string_view <-> success, string_view is remaining argument string
102 {
103 ChatCommandResult(std::nullopt_t) : _storage() {}
104 ChatCommandResult(std::string const&) = delete;
105 ChatCommandResult(std::string&& s) : _storage(std::in_place_type<std::string>, std::forward<std::string>(s)) {}
106 ChatCommandResult(char const* c) : _storage(std::in_place_type<std::string>, c) {}
107 ChatCommandResult(std::string_view s) : _storage(std::in_place_type<std::string_view>, s) {}
108
113
114 std::string_view operator*() const { return std::get<std::string_view>(_storage); }
115 bool IsSuccessful() const { return std::holds_alternative<std::string_view>(_storage); }
116 explicit operator bool() const { return IsSuccessful(); }
117 bool HasErrorMessage() const { return std::holds_alternative<std::string>(_storage); }
118 std::string const& GetErrorMessage() const { return std::get<std::string>(_storage); }
119
120 private:
121 std::variant<std::monostate, std::string_view, std::string> _storage;
122 };
123
124 TC_GAME_API void SendErrorMessageToHandler(ChatHandler* handler, std::string_view str);
125 TC_GAME_API char const* GetTrinityString(ChatHandler const* handler, TrinityStrings which);
126 template <typename... Ts>
127 std::string FormatTrinityString(ChatHandler const* handler, TrinityStrings which, Ts&&... args)
128 {
129 return fmt::sprintf(GetTrinityString(handler, which), std::forward<Ts>(args)...);
130 }
131}
132
133#endif
#define TC_GAME_API
Definition: Define.h:123
TrinityStrings
Definition: Language.h:29
TokenizeResult tokenize(std::string_view args)
static constexpr char COMMAND_DELIMITER
typename tag_base< T >::type tag_base_t
std::string FormatTrinityString(ChatHandler const *handler, TrinityStrings which, Ts &&... args)
typename get_nth< index, Ts... >::type get_nth_t
TC_GAME_API char const * GetTrinityString(ChatHandler const *handler, TrinityStrings which)
TC_GAME_API void SendErrorMessageToHandler(ChatHandler *handler, std::string_view str)
STL namespace.
ChatCommandResult(ChatCommandResult const &)=delete
ChatCommandResult(ChatCommandResult &&)=default
std::variant< std::monostate, std::string_view, std::string > _storage
ChatCommandResult & operator=(ChatCommandResult const &)=delete
ChatCommandResult & operator=(ChatCommandResult &&)=default
ChatCommandResult(std::string const &)=delete