From 2fbcbc09b02edf4a0c4c87ff7b2769f4a48638a7 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Mon, 22 May 2023 15:37:19 +0800 Subject: [PATCH] api: specialize fmt::formatter this is a part of a series to migrating from `operator<<(ostream&, ..)` based formatting to fmtlib based formatting. the goal here is to enable fmtlib to print `api::table_info` without the help of `operator<<`. but the corresponding `operator<<()` is preserved in this change, as we still have lots of callers relying on this << operator instorage_service.cc where std::vector is formatted using operator<<(ostream&, const Range&) defined in to_string.hh. we could have used fmt/ranges.h to print the std::vector. but the combination of operator<<(ostream&, const Range&) and FMT_DEPRECATED_OSTREAM renders this impossible. because unlike the builtin range formatter specializations, the fallback formatter synthesized from the operator<< does not have brackets defined for the range printer. the brackets are used as the left and right marks of the range, for instance, the array-alike containers are printed like [1,2,3], while the tuple-alike containers are printed like (1,2,3). once we are allowed to remove FMT_DEPRECATED_OSTREAM, we should be able to use the builtin range formatter, and remove the operator<< for api::table_info by then. Refs #13245 Signed-off-by: Kefu Chai Closes #13975 --- api/storage_service.cc | 7 ++++++- api/storage_service.hh | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/api/storage_service.cc b/api/storage_service.cc index faa440d380..4d756d4b40 100644 --- a/api/storage_service.cc +++ b/api/storage_service.cc @@ -55,12 +55,17 @@ extern logging::logger apilog; namespace std { std::ostream& operator<<(std::ostream& os, const api::table_info& ti) { - fmt::print(os, "table{{name={}, id={}}}", ti.name, ti.id); + fmt::print(os, "{}", ti); return os; } } // namespace std +auto fmt::formatter::format(const api::table_info& ti, + fmt::format_context& ctx) const -> decltype(ctx.out()) { + return fmt::format_to(ctx.out(), "table{{name={}, id={}}}", ti.name, ti.id); +} + namespace api { const locator::token_metadata& http_context::get_token_metadata() { diff --git a/api/storage_service.hh b/api/storage_service.hh index 6c7b0142ed..7d655ce263 100644 --- a/api/storage_service.hh +++ b/api/storage_service.hh @@ -85,3 +85,8 @@ namespace std { std::ostream& operator<<(std::ostream& os, const api::table_info& ti); } // namespace std + +template <> +struct fmt::formatter : fmt::formatter { + auto format(const api::table_info&, fmt::format_context& ctx) const -> decltype(ctx.out()); +};