diff options
Diffstat (limited to 'src/common/hobject_fmt.h')
-rw-r--r-- | src/common/hobject_fmt.h | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/common/hobject_fmt.h b/src/common/hobject_fmt.h new file mode 100644 index 000000000..622611121 --- /dev/null +++ b/src/common/hobject_fmt.h @@ -0,0 +1,53 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +#pragma once + +/** + * \file fmtlib formatters for some hobject.h classes + */ +#include <fmt/format.h> +#include <fmt/ranges.h> + +#include "common/hobject.h" +#include "include/object_fmt.h" +#include "msg/msg_fmt.h" + +// \todo reimplement +static inline void append_out_escaped(const std::string& in, std::string* out) +{ + for (auto i = in.cbegin(); i != in.cend(); ++i) { + if (*i == '%' || *i == ':' || *i == '/' || *i < 32 || *i >= 127) { + char buf[4]; + snprintf(buf, sizeof(buf), "%%%02x", (int)(unsigned char)*i); + out->append(buf); + } else { + out->push_back(*i); + } + } +} + +template <> struct fmt::formatter<hobject_t> { + + constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } + + template <typename FormatContext> auto format(const hobject_t& ho, FormatContext& ctx) + { + if (ho == hobject_t{}) { + return fmt::format_to(ctx.out(), "MIN"); + } + + if (ho.is_max()) { + return fmt::format_to(ctx.out(), "MAX"); + } + + std::string v; + append_out_escaped(ho.nspace, &v); + v.push_back(':'); + append_out_escaped(ho.get_key(), &v); + v.push_back(':'); + append_out_escaped(ho.oid.name, &v); + + return fmt::format_to(ctx.out(), "{}:{:08x}:{}:{}", static_cast<uint64_t>(ho.pool), + ho.get_bitwise_key_u32(), v, ho.snap); + } +}; |