Implement the s specifier for error_code

This commit is contained in:
Victor Zverovich
2025-04-27 08:51:18 -07:00
parent e98155a6fb
commit a7d7b894cd
2 changed files with 26 additions and 18 deletions

View File

@@ -422,6 +422,12 @@ template <> struct formatter<std::error_code> {
char c = *it; char c = *it;
if ((c >= '0' && c <= '9') || c == '{') if ((c >= '0' && c <= '9') || c == '{')
it = detail::parse_width(it, end, specs_, width_ref_, ctx); 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; return it;
} }
@@ -431,10 +437,14 @@ template <> struct formatter<std::error_code> {
auto specs = specs_; auto specs = specs_;
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
ctx); ctx);
memory_buffer buf; auto buf = memory_buffer();
buf.append(string_view(ec.category().name())); if (specs_.type() == presentation_type::string) {
buf.push_back(':'); buf.append(ec.message());
detail::write<char>(appender(buf), ec.value()); } else {
buf.append(string_view(ec.category().name()));
buf.push_back(':');
detail::write<char>(appender(buf), ec.value());
}
return detail::write<char>(ctx.out(), string_view(buf.data(), buf.size()), return detail::write<char>(ctx.out(), string_view(buf.data(), buf.size()),
specs); specs);
} }

View File

@@ -12,7 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "fmt/os.h" // fmt::system_category #include "fmt/os.h" // fmt::system_category
#include "gtest-extra.h" // StartsWith #include "gtest-extra.h" // StartsWith
#ifdef __cpp_lib_filesystem #ifdef __cpp_lib_filesystem
@@ -49,7 +49,7 @@ TEST(std_test, path) {
} }
// Intentionally delayed include to test #4303 // Intentionally delayed include to test #4303
#include "fmt/ranges.h" # include "fmt/ranges.h"
// Test ambiguity problem described in #2954. // Test ambiguity problem described in #2954.
TEST(ranges_std_test, format_vector_path) { TEST(ranges_std_test, format_vector_path) {
@@ -276,18 +276,16 @@ TEST(std_test, variant) {
TEST(std_test, error_code) { TEST(std_test, error_code) {
auto& generic = std::generic_category(); auto& generic = std::generic_category();
EXPECT_EQ("generic:42", EXPECT_EQ(fmt::format("{}", std::error_code(42, generic)), "generic:42");
fmt::format(FMT_STRING("{0}"), std::error_code(42, generic))); EXPECT_EQ(fmt::format("{:>12}", std::error_code(42, generic)),
EXPECT_EQ(" generic:42", " generic:42");
fmt::format(FMT_STRING("{:>12}"), std::error_code(42, generic))); EXPECT_EQ(fmt::format("{:12}", std::error_code(42, generic)), "generic:42 ");
EXPECT_EQ("generic:42 ", EXPECT_EQ(fmt::format("{}", std::error_code(42, fmt::system_category())),
fmt::format(FMT_STRING("{:12}"), std::error_code(42, generic))); "system:42");
EXPECT_EQ("system:42", EXPECT_EQ(fmt::format("{}", std::error_code(-42, fmt::system_category())),
fmt::format(FMT_STRING("{0}"), "system:-42");
std::error_code(42, fmt::system_category()))); auto ec = std::make_error_code(std::errc::value_too_large);
EXPECT_EQ("system:-42", EXPECT_EQ(fmt::format("{:s}", ec), ec.message());
fmt::format(FMT_STRING("{0}"),
std::error_code(-42, fmt::system_category())));
} }
template <typename Catch> void exception_test() { template <typename Catch> void exception_test() {