added more formaters

This commit is contained in:
2026-03-01 13:30:32 +03:00
parent 5eaec70846
commit cc6d625c2d
2 changed files with 84 additions and 10 deletions

View File

@@ -175,6 +175,16 @@ namespace omath
static_cast<int>(m_value.z * 255.f), static_cast<int>(m_value.z * 255.f),
static_cast<int>(m_value.w * 255.f)); static_cast<int>(m_value.w * 255.f));
} }
[[nodiscard]] std::string to_rgbf_string() const noexcept
{
return std::format("[r:{}, g:{}, b:{}, a:{}]",
m_value.x, m_value.y, m_value.z, m_value.w);
}
[[nodiscard]] std::string to_hsv_string() const noexcept
{
const auto [hue, saturation, value] = to_hsv();
return std::format("[h:{}, s:{}, v:{}]", hue, saturation, value);
}
[[nodiscard]] std::wstring to_wstring() const noexcept [[nodiscard]] std::wstring to_wstring() const noexcept
{ {
const auto ascii_string = to_string(); const auto ascii_string = to_string();
@@ -192,23 +202,55 @@ namespace omath
template<> template<>
struct std::formatter<omath::Color> // NOLINT(*-dcl58-cpp) struct std::formatter<omath::Color> // NOLINT(*-dcl58-cpp)
{ {
[[nodiscard]] enum class ColorFormat { rgb, rgbf, hsv };
static constexpr auto parse(const std::format_parse_context& ctx) ColorFormat color_format = ColorFormat::rgb;
constexpr auto parse(std::format_parse_context& ctx)
{ {
return ctx.begin(); auto it = ctx.begin();
const auto end = ctx.end();
if (it == end || *it == '}')
return it;
const std::string_view spec(it, end);
if (spec.starts_with("rgbf"))
{
color_format = ColorFormat::rgbf;
return it + 4;
}
if (spec.starts_with("rgb"))
{
color_format = ColorFormat::rgb;
return it + 3;
}
if (spec.starts_with("hsv"))
{
color_format = ColorFormat::hsv;
return it + 3;
}
throw std::format_error("Invalid format specifier for omath::Color. Use rgb, rgbf, or hsv.");
} }
template<class FormatContext> template<class FormatContext>
[[nodiscard]] auto format(const omath::Color& col, FormatContext& ctx) const
static auto format(const omath::Color& col, FormatContext& ctx)
{ {
if constexpr (std::is_same_v<typename FormatContext::char_type, char>) std::string str;
return std::format_to(ctx.out(), "{}", col.to_string()); switch (color_format)
if constexpr (std::is_same_v<typename FormatContext::char_type, wchar_t>) {
return std::format_to(ctx.out(), L"{}", col.to_wstring()); case ColorFormat::rgb: str = col.to_string(); break;
case ColorFormat::rgbf: str = col.to_rgbf_string(); break;
case ColorFormat::hsv: str = col.to_hsv_string(); break;
}
if constexpr (std::is_same_v<typename FormatContext::char_type, char>)
return std::format_to(ctx.out(), "{}", str);
if constexpr (std::is_same_v<typename FormatContext::char_type, wchar_t>)
return std::format_to(ctx.out(), L"{}", std::wstring(str.cbegin(), str.cend()));
if constexpr (std::is_same_v<typename FormatContext::char_type, char8_t>) if constexpr (std::is_same_v<typename FormatContext::char_type, char8_t>)
return std::format_to(ctx.out(), u8"{}", col.to_u8string()); return std::format_to(ctx.out(), u8"{}", std::u8string(str.cbegin(), str.cend()));
std::unreachable(); std::unreachable();
} }

View File

@@ -291,3 +291,35 @@ TEST(UnitTestColorGrouped_More2, FormatterUsesToString)
const auto formatted = std::format("{}", c); const auto formatted = std::format("{}", c);
EXPECT_NE(formatted.find("r:10"), std::string::npos); EXPECT_NE(formatted.find("r:10"), std::string::npos);
} }
TEST(UnitTestColorGrouped_More2, FormatterRgb)
{
constexpr Color c = Color::from_rgba(255, 128, 0, 64);
const auto s = std::format("{:rgb}", c);
EXPECT_NE(s.find("r:255"), std::string::npos);
EXPECT_NE(s.find("g:128"), std::string::npos);
EXPECT_NE(s.find("b:0"), std::string::npos);
EXPECT_NE(s.find("a:64"), std::string::npos);
}
TEST(UnitTestColorGrouped_More2, FormatterRgbf)
{
constexpr Color c(0.5f, 0.25f, 1.0f, 0.75f);
const auto s = std::format("{:rgbf}", c);
EXPECT_NE(s.find("r:"), std::string::npos);
EXPECT_NE(s.find("g:"), std::string::npos);
EXPECT_NE(s.find("b:"), std::string::npos);
EXPECT_NE(s.find("a:"), std::string::npos);
// Values should be in [0,1] float range, not 0-255
EXPECT_EQ(s.find("r:127"), std::string::npos);
EXPECT_EQ(s.find("r:255"), std::string::npos);
}
TEST(UnitTestColorGrouped_More2, FormatterHsv)
{
const Color c = Color::red();
const auto s = std::format("{:hsv}", c);
EXPECT_NE(s.find("h:"), std::string::npos);
EXPECT_NE(s.find("s:"), std::string::npos);
EXPECT_NE(s.find("v:"), std::string::npos);
}