From a7d7b894cdcb3e5a474338856966765e49ec956a Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 27 Apr 2025 08:51:18 -0700 Subject: [PATCH] Implement the s specifier for error_code --- include/fmt/std.h | 18 ++++++++++++++---- test/std-test.cc | 26 ++++++++++++-------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/include/fmt/std.h b/include/fmt/std.h index 1b0ea5af..62a45f42 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -422,6 +422,12 @@ template <> struct formatter { char c = *it; if ((c >= '0' && c <= '9') || c == '{') it = detail::parse_width(it, end, specs_, width_ref_, ctx); + if (it == end) return it; + + if (*it == 's') { + specs_.set_type(presentation_type::string); + ++it; + } return it; } @@ -431,10 +437,14 @@ template <> struct formatter { auto specs = specs_; detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, ctx); - memory_buffer buf; - buf.append(string_view(ec.category().name())); - buf.push_back(':'); - detail::write(appender(buf), ec.value()); + auto buf = memory_buffer(); + if (specs_.type() == presentation_type::string) { + buf.append(ec.message()); + } else { + buf.append(string_view(ec.category().name())); + buf.push_back(':'); + detail::write(appender(buf), ec.value()); + } return detail::write(ctx.out(), string_view(buf.data(), buf.size()), specs); } diff --git a/test/std-test.cc b/test/std-test.cc index 6874f025..a5c2c3c9 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -12,7 +12,7 @@ #include #include -#include "fmt/os.h" // fmt::system_category +#include "fmt/os.h" // fmt::system_category #include "gtest-extra.h" // StartsWith #ifdef __cpp_lib_filesystem @@ -49,7 +49,7 @@ TEST(std_test, path) { } // Intentionally delayed include to test #4303 -#include "fmt/ranges.h" +# include "fmt/ranges.h" // Test ambiguity problem described in #2954. TEST(ranges_std_test, format_vector_path) { @@ -276,18 +276,16 @@ TEST(std_test, variant) { TEST(std_test, error_code) { auto& generic = std::generic_category(); - EXPECT_EQ("generic:42", - fmt::format(FMT_STRING("{0}"), std::error_code(42, generic))); - EXPECT_EQ(" generic:42", - fmt::format(FMT_STRING("{:>12}"), std::error_code(42, generic))); - EXPECT_EQ("generic:42 ", - fmt::format(FMT_STRING("{:12}"), std::error_code(42, generic))); - EXPECT_EQ("system:42", - fmt::format(FMT_STRING("{0}"), - std::error_code(42, fmt::system_category()))); - EXPECT_EQ("system:-42", - fmt::format(FMT_STRING("{0}"), - std::error_code(-42, fmt::system_category()))); + EXPECT_EQ(fmt::format("{}", std::error_code(42, generic)), "generic:42"); + EXPECT_EQ(fmt::format("{:>12}", std::error_code(42, generic)), + " generic:42"); + EXPECT_EQ(fmt::format("{:12}", std::error_code(42, generic)), "generic:42 "); + EXPECT_EQ(fmt::format("{}", std::error_code(42, fmt::system_category())), + "system:42"); + EXPECT_EQ(fmt::format("{}", std::error_code(-42, fmt::system_category())), + "system:-42"); + auto ec = std::make_error_code(std::errc::value_too_large); + EXPECT_EQ(fmt::format("{:s}", ec), ec.message()); } template void exception_test() {