mirror of
https://github.com/scylladb/scylladb.git
synced 2026-05-31 12:06:44 +00:00
format_parse_context::on_error() is an undocumented API in fmt v9 and in fmt v10, see - https://fmt.dev/9.1.0/api.html#_CPPv4I0EN3fmt16basic_format_argE - https://fmt.dev/10.0.0/api.html#_CPPv4I0EN3fmt26basic_format_parse_contextE despite that this API was once used in its document for fmt v10.0.0, see https://fmt.dev/10.0.0/api.html#formatting-user-defined-types. it's still, well, undocumented. so, to have better compatibility, let's use the documented API in place of undocumented one. please note, `throw_format_error()` was still not a public API before 10.1.0, so before that release we have to throw `fmt::format_error` explicitly. so we cannot use it yet during the transitional period. because the class of `fmt::format_error` is defined in `fmt/format.h`, we need to include this header for using it. Refs #13245 Signed-off-by: Kefu Chai <kefu.chai@scylladb.com> Closes scylladb/scylladb#16212
90 lines
2.6 KiB
C++
90 lines
2.6 KiB
C++
/*
|
|
* Copyright (C) 2023-present ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <chrono>
|
|
#include <fmt/format.h>
|
|
|
|
namespace utils {
|
|
|
|
class pretty_printed_data_size {
|
|
uint64_t _size;
|
|
public:
|
|
pretty_printed_data_size(uint64_t size) : _size(size) {}
|
|
|
|
friend fmt::formatter<pretty_printed_data_size>;
|
|
};
|
|
|
|
class pretty_printed_throughput {
|
|
uint64_t _size;
|
|
std::chrono::duration<float> _duration;
|
|
public:
|
|
pretty_printed_throughput(uint64_t size, std::chrono::duration<float> dur) : _size(size), _duration(std::move(dur)) {}
|
|
|
|
friend fmt::formatter<pretty_printed_throughput>;
|
|
};
|
|
|
|
|
|
}
|
|
|
|
// print data_size using IEC or SI binary prefix annotation with optional "B"
|
|
// or " bytes" unit postfix.
|
|
//
|
|
// usage:
|
|
// fmt::print("{}", 10'024); // prints "10kB", using SI and add the "B" unit
|
|
// // postfix by default
|
|
// fmt::print("{:i}", 42); // prints "42 bytes"
|
|
// fmt::print("{:ib}", 10'024); // prints "10Ki", IEC unit is used, without
|
|
// // the " bytes" or "B" unit
|
|
// fmt::print("{:s}", 10); // prints "10 bytes", SI unit is used
|
|
// fmt::print("{:sb}", 10'000); // prints "10k", SI unit is used, without
|
|
// // the unit postfix
|
|
template <>
|
|
struct fmt::formatter<utils::pretty_printed_data_size> {
|
|
enum class prefix_type {
|
|
SI,
|
|
IEC,
|
|
};
|
|
prefix_type _prefix = prefix_type::SI;
|
|
bool _bytes = true;
|
|
constexpr auto parse(format_parse_context& ctx) {
|
|
auto it = ctx.begin();
|
|
auto end = ctx.end();
|
|
if (it != end) {
|
|
if (*it == 's') {
|
|
_prefix = prefix_type::SI;
|
|
++it;
|
|
} else if (*it == 'i') {
|
|
_prefix = prefix_type::IEC;
|
|
++it;
|
|
}
|
|
if (*it == 'b') {
|
|
_bytes = false;
|
|
++it;
|
|
}
|
|
}
|
|
if (it != end && *it != '}') {
|
|
throw fmt::format_error("invalid format specifier");
|
|
}
|
|
return it;
|
|
}
|
|
template <typename FormatContext>
|
|
auto format(utils::pretty_printed_data_size, FormatContext& ctx) const -> decltype(ctx.out());
|
|
};
|
|
|
|
template <>
|
|
struct fmt::formatter<utils::pretty_printed_throughput>
|
|
: private fmt::formatter<utils::pretty_printed_data_size> {
|
|
using size_formatter = fmt::formatter<utils::pretty_printed_data_size>;
|
|
public:
|
|
using size_formatter::parse;
|
|
template <typename FormatContext>
|
|
auto format(const utils::pretty_printed_throughput&, FormatContext& ctx) const -> decltype(ctx.out());
|
|
};
|