From 079d70145e9e07aff97ce3cbc89b873247759e8d Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Thu, 7 Mar 2024 14:10:42 +0800 Subject: [PATCH] raft: add fmt::formatter for raft tracker types before this change, we rely on the default-generated fmt::formatter created from operator<<, but fmt v10 dropped the default-generated formatter. in this change, we define formatters for * raft::election_tracker * raft::votes * raft::vote_result and drop their operator<<:s. Refs #13245 Signed-off-by: Kefu Chai Closes scylladb/scylladb#17670 --- raft/tracker.cc | 66 ++++++++++++++++++++++--------------------- raft/tracker.hh | 18 +++++++++--- test/raft/fsm_test.cc | 10 +++++++ 3 files changed, 58 insertions(+), 36 deletions(-) diff --git a/raft/tracker.cc b/raft/tracker.cc index e0ea1d257e..ab911ba8f5 100644 --- a/raft/tracker.cc +++ b/raft/tracker.cc @@ -256,36 +256,38 @@ vote_result votes::tally_votes() const { return _current.tally_votes(); } -std::ostream& operator<<(std::ostream& os, const election_tracker& v) { - os << "responded: " << v._responded.size() << ", "; - os << "granted: " << v._granted; - return os; -} - - -std::ostream& operator<<(std::ostream& os, const votes& v) { - os << "current: " << v._current << std::endl; - if (v._previous) { - os << "previous: " << v._previous.value() << std::endl; - } - return os; -} - -std::ostream& operator<<(std::ostream& os, const vote_result& v) { - static const char *n; - switch (v) { - case vote_result::UNKNOWN: - n = "UNKNOWN"; - break; - case vote_result::WON: - n = "WON"; - break; - case vote_result::LOST: - n = "LOST"; - break; - } - os << n; - return os; -} - } // end of namespace raft + +auto fmt::formatter::format(const raft::election_tracker& v, fmt::format_context& ctx) const + -> decltype(ctx.out()) { + return fmt::format_to(ctx.out(), "responded: {}, granted: {}", + v._responded.size(), v._granted); +} + +auto fmt::formatter::format(const raft::votes& v, fmt::format_context& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + out = fmt::format_to(out, "current: {}\n", v._current); + if (v._previous) { + out = fmt::format_to(out, "previous: {}\n", v._previous.value()); + } + return out; +} + +auto fmt::formatter::format(const raft::vote_result& v, fmt::format_context& ctx) const + -> decltype(ctx.out()) { + std::string_view name; + using enum raft::vote_result; + switch (v) { + case UNKNOWN: + name = "UNKNOWN"; + break; + case WON: + name = "WON"; + break; + case LOST: + name = "LOST"; + break; + } + return formatter::format(name, ctx); +} diff --git a/raft/tracker.hh b/raft/tracker.hh index 2ea3aa8e9d..dac60c3d39 100644 --- a/raft/tracker.hh +++ b/raft/tracker.hh @@ -8,6 +8,7 @@ #pragma once #include +#include #include "raft.hh" namespace raft { @@ -145,8 +146,6 @@ enum class vote_result { LOST, }; -std::ostream& operator<<(std::ostream& os, const vote_result& v); - // State of election in a single quorum class election_tracker { // All eligible voters @@ -182,7 +181,7 @@ public: auto unknown = _suffrage.size() - _responded.size(); return _granted + unknown >= quorum ? vote_result::UNKNOWN : vote_result::LOST; } - friend std::ostream& operator<<(std::ostream& os, const election_tracker& v); + friend fmt::formatter; }; // Candidate's state specific to election @@ -202,8 +201,19 @@ public: void register_vote(server_id from, bool granted); vote_result tally_votes() const; - friend std::ostream& operator<<(std::ostream& os, const votes& v); + friend fmt::formatter; }; } // namespace raft +template <> struct fmt::formatter : fmt::formatter { + auto format(const raft::election_tracker& v, fmt::format_context& ctx) const -> decltype(ctx.out()); +}; + +template <> struct fmt::formatter : fmt::formatter { + auto format(const raft::votes& v, fmt::format_context& ctx) const -> decltype(ctx.out()); +}; + +template <> struct fmt::formatter : fmt::formatter { + auto format(const raft::vote_result& v, fmt::format_context& ctx) const -> decltype(ctx.out()); +}; diff --git a/test/raft/fsm_test.cc b/test/raft/fsm_test.cc index f9c74340a1..b0fd19fa26 100644 --- a/test/raft/fsm_test.cc +++ b/test/raft/fsm_test.cc @@ -8,10 +8,20 @@ #define BOOST_TEST_MODULE raft +#include "raft/tracker.hh" #include "test/raft/helpers.hh" using namespace raft; +namespace raft { + +std::ostream& boost_test_print_type(std::ostream& os, const vote_result& v) { + fmt::print(os, "{}", v); + return os; +} + +} + BOOST_AUTO_TEST_CASE(test_votes) { auto id1 = id();