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) {
using namespace jessilib::io;
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();
}, u8"quit" };
@ -40,19 +40,19 @@ command help_command{ [](command_context& context) {
if (table_name.empty()) {
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;
}
// table examples: "console", "irc", "irc+", "irc%", "irc@"; should table instead be 'tables'?
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
const command_manager& manager = command_manager::instance();
manager.foreach([&context](basic_command* in_command) {
context.publicReply(formatted_message{ "{}", in_command->label() });
context.publicReply(formatted_message{ u8"{}", in_command->label() });
return true;
});
}, u8"help" };

4
src/bot/console/console.cpp

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

2
src/bot/console/console_command_context.hpp

@ -33,7 +33,7 @@ public:
/** Additional contextual details */
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
} // 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
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'
// Graphics modes
@ -42,16 +42,16 @@ static constexpr uint8_t CONCEALED{ '8' };
static constexpr uint8_t GRAPHICS_SEP{ ';' };
static constexpr uint8_t GRAPHICS_END{ 'm' };
static constexpr std::string_view COLOR_HEX{ "38;2" };
static constexpr std::string_view COLOR_DEFAULT{ "39" };
static constexpr std::string_view COLOR_BG_HEX{ "48;2" };
static constexpr std::string_view COLOR_BG_DEFAULT{ "49" };
static constexpr std::u8string_view COLOR_HEX{ u8"38;2" };
static constexpr std::u8string_view COLOR_DEFAULT{ u8"39" };
static constexpr std::u8string_view COLOR_BG_HEX{ u8"48;2" };
static constexpr std::u8string_view COLOR_BG_DEFAULT{ u8"49" };
} // namespace ansi
template<>
inline std::string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper& in_text) {
std::string result;
inline std::u8string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper& in_text) {
std::u8string result;
result.reserve(in_text.string().size() + 8);
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
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
@ -100,7 +105,7 @@ inline std::string text_to_string<ansi::text_wrapper>(const ansi::text_wrapper&
}
// Append textual string
result += jessilib::ustring_to_mbstring(std::u8string_view{in_text.string()}).second;
result += in_text.string();
// Reset (if needed)
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
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>
auto format(const jessilib::io::ansi::text_wrapper& in_text, FormatContext& in_context) {
// 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 */
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:
string_type m_input;

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

@ -18,7 +18,7 @@
#pragma once
#include "io/message.hpp"
#include "jessilib/io/message.hpp"
namespace jessilib {
namespace io {
@ -45,19 +45,19 @@ static constexpr color s_irc_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)
"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
// Extended colors (16-98, making a total of 99 color choices)
"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", "72", "73", "74", "75",
"76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87",
"88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98"
u8"16", u8"17", u8"18", u8"19", u8"20", u8"21", u8"22", u8"23", u8"24", u8"25", u8"26", u8"27",
u8"28", u8"29", u8"30", u8"31", u8"32", u8"33", u8"34", u8"35", u8"36", u8"37", u8"38", u8"39",
u8"40", u8"41", u8"42", u8"43", u8"44", u8"45", u8"46", u8"47", u8"48", u8"49", u8"50", u8"51",
u8"52", u8"53", u8"54", u8"55", u8"56", u8"57", u8"58", u8"59", u8"60", u8"61", u8"62", u8"63",
u8"64", u8"65", u8"66", u8"67", u8"68", u8"69", u8"70", u8"71", u8"72", u8"73", u8"74", u8"75",
u8"76", u8"77", u8"78", u8"79", u8"80", u8"81", u8"82", u8"83", u8"84", u8"85", u8"86", u8"87",
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
};
@ -98,7 +98,7 @@ constexpr color normalize_color(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)];
}
@ -112,7 +112,7 @@ static constexpr uint8_t COLOR_HEX{ 0x04 };
static constexpr uint8_t REVERSE{ 0x16 };
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 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
template<>
inline std::string text_to_string<irc::text_wrapper>(const irc::text_wrapper& in_text) {
std::string result;
inline std::u8string text_to_string<irc::text_wrapper>(const irc::text_wrapper& in_text) {
std::u8string result;
result.reserve(in_text.string().size() + 8);
// Prepend properties
@ -178,10 +178,10 @@ inline std::string text_to_string<irc::text_wrapper>(const irc::text_wrapper& in
} // namespace jessilib
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>
auto format(const jessilib::io::irc::text_wrapper& in_text, FormatContext& in_context) {
// 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 <type_traits>
#include <fmt/format.h>
#include <fmt/xchar.h>
#include "jessilib/unicode.hpp"
#include "color.hpp"
@ -155,13 +156,13 @@ private:
class formatted_message {
public:
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_message{ std::forward<Args>(args)... } {
// Empty ctor body
}
const std::string& format() const {
const std::u8string& format() const {
return m_format;
}
@ -170,12 +171,12 @@ public:
}
private:
std::string m_format;
std::u8string m_format;
std::vector<text> m_message;
};
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();
}
@ -209,18 +210,23 @@ std::string process_message(const jessilib::io::message& msg) {
}
template<typename WrapperT>
std::string process_message(const jessilib::io::formatted_message& msg) {
using format_arg = fmt::format_args::format_arg;
std::vector<format_arg> args;
std::u8string process_message(const jessilib::io::formatted_message& msg) {
using FormatCharT = char8_t;
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
std::vector<format_arg_type> args;
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
fmt::format_args text_args{ args.data(), static_cast<int>(args.size()) };
return fmt::vformat(msg.format(), text_args);
format_args_type text_args{ args.data(), static_cast<int>(args.size()) };
string_view_type fmt_view{ msg.format().data(), msg.format().size() };
return fmt::vformat(fmt_view, text_args);
}
} // namespace io

Loading…
Cancel
Save