Browse Source

Use char8_t with fmtlib

master
Jessica James 3 years ago
parent
commit
647e08e6a3
  1. 8
      src/bot/base_commands.cpp
  2. 4
      src/bot/console/console.cpp
  3. 2
      src/bot/console/console_command_context.cpp
  4. 2
      src/bot/console/console_command_context.hpp
  5. 2
      src/external/fmt
  6. 27
      src/include/jessilib/io/ansi/ansi_text.hpp
  7. 2
      src/include/jessilib/io/command_context.hpp
  8. 32
      src/include/jessilib/io/irc/irc_text.hpp
  9. 26
      src/include/jessilib/io/message.hpp

8
src/bot/base_commands.cpp

@ -29,7 +29,7 @@ using namespace std::literals;
command quit_command{ [](command_context& context) { command quit_command{ [](command_context& context) {
using namespace jessilib::io; using namespace jessilib::io;
text quit_text{ u8"Closing jessibot", text::property::bold, color{ 0xFF0000 } }; // TODO: localize text quit_text{ u8"Closing jessibot", text::property::bold, color{ 0xFF0000 } }; // TODO: localize
context.publicReply(formatted_message{ "{}", quit_text }); context.publicReply(formatted_message{ u8"{}", quit_text });
notify_shutdown(); notify_shutdown();
}, u8"quit" }; }, u8"quit" };
@ -40,19 +40,19 @@ command help_command{ [](command_context& context) {
if (table_name.empty()) { if (table_name.empty()) {
text error_text{ u8"ERROR", text::property::bold, color{ 0xFF0000 } }; // TODO: localize text error_text{ u8"ERROR", text::property::bold, color{ 0xFF0000 } }; // TODO: localize
context.publicReply(formatted_message{ "{} command context is missing permission table name", error_text }); context.publicReply(formatted_message{ u8"{} command context is missing permission table name", error_text });
return; return;
} }
// table examples: "console", "irc", "irc+", "irc%", "irc@"; should table instead be 'tables'? // table examples: "console", "irc", "irc+", "irc%", "irc@"; should table instead be 'tables'?
text table_text{ table_name, text::property::bold, color{ 0x0000FF } }; text table_text{ table_name, text::property::bold, color{ 0x0000FF } };
context.publicReply(formatted_message{ "Commands for table '{}':", table_text }); context.publicReply(formatted_message{ u8"Commands for table '{}':", table_text });
// TODO: read some permission table and filter commands based upon permission and context information // TODO: read some permission table and filter commands based upon permission and context information
const command_manager& manager = command_manager::instance(); const command_manager& manager = command_manager::instance();
manager.foreach([&context](basic_command* in_command) { manager.foreach([&context](basic_command* in_command) {
context.publicReply(formatted_message{ "{}", in_command->label() }); context.publicReply(formatted_message{ u8"{}", in_command->label() });
return true; return true;
}); });
}, u8"help" }; }, u8"help" };

4
src/bot/console/console.cpp

@ -38,8 +38,8 @@ void console_input_loop() {
if (!command_manager::instance().execute_command(context)) { if (!command_manager::instance().execute_command(context)) {
text error_text{ u8"ERROR", text::property::bold, color{ 0xFF0000 }}; text error_text{ u8"ERROR", text::property::bold, color{ 0xFF0000 }};
text keyword_text{ context.keyword(), text::property::bold, color{ 0x0000FF }}; text keyword_text{ context.keyword(), text::property::bold, color{ 0x0000FF }};
auto result = process_message<ansi::text_wrapper>(formatted_message{"{} Command \"{}\" not found", error_text, keyword_text}); auto result = process_message<ansi::text_wrapper>(formatted_message{u8"{} Command \"{}\" not found", error_text, keyword_text});
std::cout << result << std::endl; std::wcout << jessilib::string_cast<wchar_t>(result) << std::endl;
} }
} }
} }

2
src/bot/console/console_command_context.cpp

@ -47,7 +47,7 @@ jessilib::object console_command_context::details() const {
return s_details; return s_details;
} }
std::string console_command_context::getText(std::string_view tag) const { std::u8string console_command_context::getText(std::u8string_view tag) const {
return { tag.begin(), tag.end() }; // TODO: implement properly return { tag.begin(), tag.end() }; // TODO: implement properly
} }

2
src/bot/console/console_command_context.hpp

@ -33,7 +33,7 @@ public:
/** Additional contextual details */ /** Additional contextual details */
jessilib::object details() const override; jessilib::object details() const override;
std::string getText(std::string_view tag) const override; std::u8string getText(std::u8string_view tag) const override;
}; // class console_command_context }; // class console_command_context
} // namespace io } // namespace io

2
src/external/fmt

@ -1 +1 @@
Subproject commit 812733cc963b2e1d96f6ad2cb2d441c6fe8e4a5b Subproject commit 9d5b9defde1334726d35c0d21b6225511ed3976e

27
src/include/jessilib/io/ansi/ansi_text.hpp

@ -29,7 +29,7 @@ class text_wrapper : public text {};
// Control characters // Control characters
static constexpr uint8_t ESCAPE_CHR{ 0x1B }; static constexpr uint8_t ESCAPE_CHR{ 0x1B };
static constexpr std::string_view ESCAPE{ "\x1B[" }; static constexpr std::u8string_view ESCAPE{ u8"\x1B[" };
// ESCAPE + '[' + <color or graphics code list> + 'm' // ESCAPE + '[' + <color or graphics code list> + 'm'
// Graphics modes // Graphics modes
@ -42,16 +42,16 @@ static constexpr uint8_t CONCEALED{ '8' };
static constexpr uint8_t GRAPHICS_SEP{ ';' }; static constexpr uint8_t GRAPHICS_SEP{ ';' };
static constexpr uint8_t GRAPHICS_END{ 'm' }; static constexpr uint8_t GRAPHICS_END{ 'm' };
static constexpr std::string_view COLOR_HEX{ "38;2" }; static constexpr std::u8string_view COLOR_HEX{ u8"38;2" };
static constexpr std::string_view COLOR_DEFAULT{ "39" }; static constexpr std::u8string_view COLOR_DEFAULT{ u8"39" };
static constexpr std::string_view COLOR_BG_HEX{ "48;2" }; static constexpr std::u8string_view COLOR_BG_HEX{ u8"48;2" };
static constexpr std::string_view COLOR_BG_DEFAULT{ "49" }; static constexpr std::u8string_view COLOR_BG_DEFAULT{ u8"49" };
} // namespace ansi } // namespace ansi
template<> template<>
inline std::string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper& in_text) { inline std::u8string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper& in_text) {
std::string result; std::u8string result;
result.reserve(in_text.string().size() + 8); result.reserve(in_text.string().size() + 8);
auto set_graphic_option = [&result](auto in_option) { auto set_graphic_option = [&result](auto in_option) {
@ -65,7 +65,12 @@ inline std::string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper&
} }
// Append graphics option // Append graphics option
result += in_option; if constexpr (std::is_same_v<decltype(in_option), std::string>) {
result += jessilib::string_view_cast<char8_t>(in_option);
}
else {
result += in_option;
}
}; };
// Set graphics properties // Set graphics properties
@ -100,7 +105,7 @@ inline std::string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper&
} }
// Append textual string // Append textual string
result += jessilib::ustring_to_mbstring(std::u8string_view{in_text.string()}).second; result += in_text.string();
// Reset (if needed) // Reset (if needed)
if (in_text.properties() != text::property::normal) { if (in_text.properties() != text::property::normal) {
@ -117,10 +122,10 @@ inline std::string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper&
} // namespace jessilib } // namespace jessilib
template<> template<>
struct fmt::formatter<jessilib::io::ansi::text_wrapper> : formatter<std::string> { struct fmt::formatter<jessilib::io::ansi::text_wrapper, char8_t> : formatter<std::u8string, char8_t> {
template <typename FormatContext> template <typename FormatContext>
auto format(const jessilib::io::ansi::text_wrapper& in_text, FormatContext& in_context) { auto format(const jessilib::io::ansi::text_wrapper& in_text, FormatContext& in_context) {
// Pass result to base // Pass result to base
return formatter<std::string>::format(jessilib::io::text_to_string(in_text), in_context); return formatter<std::u8string, char8_t>::format(jessilib::io::text_to_string(in_text), in_context);
} }
}; };

2
src/include/jessilib/io/command_context.hpp

@ -43,7 +43,7 @@ public:
/** Additional contextual details */ /** Additional contextual details */
virtual object details() const = 0; // Additional details virtual object details() const = 0; // Additional details
virtual std::string getText(std::string_view tag) const = 0; // Get localized text virtual std::u8string getText(std::u8string_view tag) const = 0; // Get localized text
private: private:
string_type m_input; string_type m_input;

32
src/include/jessilib/io/irc/irc_text.hpp

@ -18,7 +18,7 @@
#pragma once #pragma once
#include "io/message.hpp" #include "jessilib/io/message.hpp"
namespace jessilib { namespace jessilib {
namespace io { namespace io {
@ -45,19 +45,19 @@ static constexpr color s_irc_colors[] {
#endif // JESSILIB_IRC_SIMPLE_COLORS #endif // JESSILIB_IRC_SIMPLE_COLORS
}; };
static constexpr std::string_view s_irc_color_codes[] { static constexpr std::u8string_view s_irc_color_codes[] {
// Basic 16 colors (0-15) // Basic 16 colors (0-15)
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", u8"00", u8"01", u8"02", u8"03", u8"04", u8"05", u8"06", u8"07", u8"08", u8"09", u8"10", u8"11", u8"12", u8"13", u8"14", u8"15",
#ifndef JESSILIB_IRC_SIMPLE_COLORS #ifndef JESSILIB_IRC_SIMPLE_COLORS
// Extended colors (16-98, making a total of 99 color choices) // Extended colors (16-98, making a total of 99 color choices)
"16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", u8"16", u8"17", u8"18", u8"19", u8"20", u8"21", u8"22", u8"23", u8"24", u8"25", u8"26", u8"27",
"28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", u8"28", u8"29", u8"30", u8"31", u8"32", u8"33", u8"34", u8"35", u8"36", u8"37", u8"38", u8"39",
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", u8"40", u8"41", u8"42", u8"43", u8"44", u8"45", u8"46", u8"47", u8"48", u8"49", u8"50", u8"51",
"52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", u8"52", u8"53", u8"54", u8"55", u8"56", u8"57", u8"58", u8"59", u8"60", u8"61", u8"62", u8"63",
"64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", u8"64", u8"65", u8"66", u8"67", u8"68", u8"69", u8"70", u8"71", u8"72", u8"73", u8"74", u8"75",
"76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", u8"76", u8"77", u8"78", u8"79", u8"80", u8"81", u8"82", u8"83", u8"84", u8"85", u8"86", u8"87",
"88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98" u8"88", u8"89", u8"90", u8"91", u8"92", u8"93", u8"94", u8"95", u8"96", u8"97", u8"98"
#endif // JESSILIB_IRC_SIMPLE_COLORS #endif // JESSILIB_IRC_SIMPLE_COLORS
}; };
@ -98,7 +98,7 @@ constexpr color normalize_color(color in_color) {
return s_irc_colors[from_color(in_color)]; return s_irc_colors[from_color(in_color)];
} }
constexpr std::string_view color_to_code(color in_color) { constexpr std::u8string_view color_to_code(color in_color) {
return s_irc_color_codes[from_color(in_color)]; return s_irc_color_codes[from_color(in_color)];
} }
@ -112,7 +112,7 @@ static constexpr uint8_t COLOR_HEX{ 0x04 };
static constexpr uint8_t REVERSE{ 0x16 }; static constexpr uint8_t REVERSE{ 0x16 };
static constexpr uint8_t NORMAL{ 0x0F }; static constexpr uint8_t NORMAL{ 0x0F };
text::property properties_to_toggle(text::property in_active_properties, text::property in_text_properties, uint8_t in_active_color, uint8_t in_text_color, uint8_t in_active_color_bg, uint8_t in_text_color_bg) { inline text::property properties_to_toggle(text::property in_active_properties, text::property in_text_properties, uint8_t in_active_color, uint8_t in_text_color, uint8_t in_active_color_bg, uint8_t in_text_color_bg) {
text::property_backing_t active_properties_backing = static_cast<text::property_backing_t>(in_active_properties); text::property_backing_t active_properties_backing = static_cast<text::property_backing_t>(in_active_properties);
text::property_backing_t text_properties_backing = static_cast<text::property_backing_t>(in_text_properties); text::property_backing_t text_properties_backing = static_cast<text::property_backing_t>(in_text_properties);
@ -138,8 +138,8 @@ text::property properties_to_toggle(text::property in_active_properties, text::p
} // namespace irc } // namespace irc
template<> template<>
inline std::string text_to_string<irc::text_wrapper>(const irc::text_wrapper& in_text) { inline std::u8string text_to_string<irc::text_wrapper>(const irc::text_wrapper& in_text) {
std::string result; std::u8string result;
result.reserve(in_text.string().size() + 8); result.reserve(in_text.string().size() + 8);
// Prepend properties // Prepend properties
@ -178,10 +178,10 @@ inline std::string text_to_string<irc::text_wrapper>(const irc::text_wrapper& in
} // namespace jessilib } // namespace jessilib
template<> template<>
struct fmt::formatter<jessilib::io::irc::text_wrapper> : formatter<std::string> { struct fmt::formatter<jessilib::io::irc::text_wrapper, char8_t> : formatter<std::u8string, char8_t> {
template <typename FormatContext> template <typename FormatContext>
auto format(const jessilib::io::irc::text_wrapper& in_text, FormatContext& in_context) { auto format(const jessilib::io::irc::text_wrapper& in_text, FormatContext& in_context) {
// Pass result to base // Pass result to base
return formatter<std::string>::format(jessilib::io::text_to_string(in_text), in_context); return formatter<std::u8string, char8_t>::format(jessilib::io::text_to_string(in_text), in_context);
} }
}; };

26
src/include/jessilib/io/message.hpp

@ -23,6 +23,7 @@
#include <string_view> #include <string_view>
#include <type_traits> #include <type_traits>
#include <fmt/format.h> #include <fmt/format.h>
#include <fmt/xchar.h>
#include "jessilib/unicode.hpp" #include "jessilib/unicode.hpp"
#include "color.hpp" #include "color.hpp"
@ -155,13 +156,13 @@ private:
class formatted_message { class formatted_message {
public: public:
template<typename... Args> template<typename... Args>
formatted_message(std::string in_format, Args&& ... args) formatted_message(std::u8string in_format, Args&& ... args)
: m_format{ std::move(in_format) }, : m_format{ std::move(in_format) },
m_message{ std::forward<Args>(args)... } { m_message{ std::forward<Args>(args)... } {
// Empty ctor body // Empty ctor body
} }
const std::string& format() const { const std::u8string& format() const {
return m_format; return m_format;
} }
@ -170,12 +171,12 @@ public:
} }
private: private:
std::string m_format; std::u8string m_format;
std::vector<text> m_message; std::vector<text> m_message;
}; };
template<typename WrapperT> template<typename WrapperT>
std::string text_to_string(const WrapperT& in_text) { std::u8string text_to_string(const WrapperT& in_text) {
return in_text.string(); return in_text.string();
} }
@ -209,18 +210,23 @@ std::string process_message(const jessilib::io::message& msg) {
} }
template<typename WrapperT> template<typename WrapperT>
std::string process_message(const jessilib::io::formatted_message& msg) { std::u8string process_message(const jessilib::io::formatted_message& msg) {
using format_arg = fmt::format_args::format_arg; using FormatCharT = char8_t;
std::vector<format_arg> args; using format_args_type = fmt::basic_format_args<fmt::buffer_context<FormatCharT>>;
using format_arg_type = format_args_type::format_arg;
using format_context_type = fmt::buffer_context<FormatCharT>;
using string_view_type = fmt::v8::basic_string_view<FormatCharT>;
// Populate args // Populate args
std::vector<format_arg_type> args;
for (auto& text : msg.get_message()) { for (auto& text : msg.get_message()) {
args.emplace_back(fmt::detail::make_arg<fmt::format_context>(wrap_text<WrapperT>(text))); args.emplace_back(fmt::detail::make_arg<format_context_type>(wrap_text<WrapperT>(text)));
} }
// Pass args into vformat // Pass args into vformat
fmt::format_args text_args{ args.data(), static_cast<int>(args.size()) }; format_args_type text_args{ args.data(), static_cast<int>(args.size()) };
return fmt::vformat(msg.format(), text_args); string_view_type fmt_view{ msg.format().data(), msg.format().size() };
return fmt::vformat(fmt_view, text_args);
} }
} // namespace io } // namespace io

Loading…
Cancel
Save