/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#ifndef TRINITY_CHATCOMMANDHELPERS_H
#define TRINITY_CHATCOMMANDHELPERS_H
#include "Define.h"
#include "Language.h"
#include "Optional.h"
#include "StringFormat.h"
#include
#include
#include
#include
#include
class ChatHandler;
namespace Trinity::Impl::ChatCommands
{
/***************** HELPERS *************************\
|* These really aren't for outside use... *|
\***************************************************/
static constexpr char COMMAND_DELIMITER = ' ';
template
struct tag_base
{
using type = T;
};
template
using tag_base_t = typename tag_base::type;
struct TokenizeResult {
explicit operator bool() { return !token.empty(); }
std::string_view token;
std::string_view tail;
};
inline TokenizeResult tokenize(std::string_view args)
{
TokenizeResult result;
if (size_t delimPos = args.find(COMMAND_DELIMITER); delimPos != std::string_view::npos)
{
result.token = args.substr(0, delimPos);
if (size_t tailPos = args.find_first_not_of(COMMAND_DELIMITER, delimPos); tailPos != std::string_view::npos)
result.tail = args.substr(tailPos);
}
else
result.token = args;
return result;
}
template
struct are_all_assignable
{
static constexpr bool value = (std::is_assignable_v && ...);
};
template
struct are_all_assignable
{
static constexpr bool value = false;
};
template
struct get_nth : get_nth { };
template
struct get_nth<0, T1, Ts...>
{
using type = T1;
};
template
using get_nth_t = typename get_nth::type;
// this essentially models std::optional, except it can also hold an error message
// it has std::string_view's bool conversion and dereference operators
//
// monostate <-> unspecified error, typically end-of-string reached or parsing failed
// std::string <-> specified error, typically character-not-found or invalid item link
// std::string_view <-> success, string_view is remaining argument string
struct ChatCommandResult
{
ChatCommandResult(std::nullopt_t) : _storage() {}
ChatCommandResult(std::string const&) = delete;
ChatCommandResult(std::string&& s) : _storage(std::in_place_type, std::forward(s)) {}
ChatCommandResult(char const* c) : _storage(std::in_place_type, c) {}
ChatCommandResult(std::string_view s) : _storage(std::in_place_type, s) {}
ChatCommandResult(ChatCommandResult const&) = delete;
ChatCommandResult(ChatCommandResult&&) = default;
ChatCommandResult& operator=(ChatCommandResult const&) = delete;
ChatCommandResult& operator=(ChatCommandResult&&) = default;
std::string_view operator*() const { return std::get(_storage); }
bool IsSuccessful() const { return std::holds_alternative(_storage); }
explicit operator bool() const { return IsSuccessful(); }
bool HasErrorMessage() const { return std::holds_alternative(_storage); }
std::string const& GetErrorMessage() const { return std::get(_storage); }
private:
std::variant _storage;
};
TC_GAME_API void SendErrorMessageToHandler(ChatHandler* handler, std::string_view str);
TC_GAME_API char const* GetTrinityString(ChatHandler const* handler, TrinityStrings which);
TC_GAME_API std::string FormatTrinityString(std::string_view messageFormat, fmt::printf_args messageFormatArgs);
template
std::string FormatTrinityString(ChatHandler const* handler, TrinityStrings which, Ts&&... args)
{
return FormatTrinityString(GetTrinityString(handler, which), fmt::make_printf_args(std::forward(args)...));
}
}
#endif