103 lines
2.9 KiB
C++
103 lines
2.9 KiB
C++
#ifndef msgpack_test_utils_4573e6627d8efe78
|
|
#define msgpack_test_utils_4573e6627d8efe78
|
|
|
|
// clang-format off : Must include fmt/format before extra/formatters.
|
|
#include <fmt/format.h>
|
|
|
|
#include "parselink/msgpack/extra/formatters.h"
|
|
// clang-format on
|
|
|
|
#include <tl/expected.hpp>
|
|
|
|
#include <boost/ut.hpp>
|
|
#include <magic_enum.hpp>
|
|
#include <magic_enum_format.hpp>
|
|
|
|
#include <source_location>
|
|
|
|
namespace test {
|
|
|
|
template <typename T>
|
|
inline constexpr std::array<std::byte, sizeof(T)> as_bytes(T&& t) {
|
|
return std::bit_cast<std::array<std::byte, sizeof(T)>>(std::forward<T>(t));
|
|
}
|
|
|
|
template <typename... Bytes>
|
|
inline constexpr std::array<std::byte, sizeof...(Bytes)> make_bytes(
|
|
Bytes&&... bytes) noexcept {
|
|
return {std::byte(std::forward<Bytes>(bytes))...};
|
|
}
|
|
|
|
} // namespace test
|
|
|
|
// This formatter allows expected values to be formatted for both its expected
|
|
// and unexpected types.
|
|
template <typename T, typename E>
|
|
struct fmt::formatter<tl::expected<T, E>> {
|
|
int width = 0;
|
|
|
|
fmt::formatter<T> t_fmtr;
|
|
fmt::formatter<E> e_fmtr;
|
|
|
|
constexpr auto parse(auto& ctx) {
|
|
using char_type =
|
|
typename std::remove_reference_t<decltype(ctx)>::char_type;
|
|
auto delim = char_type{'|'};
|
|
auto close_brace = char_type{'}'};
|
|
std::array<char_type, 32> fmtbuf;
|
|
|
|
if (ctx.begin() == ctx.end() || *ctx.begin() == '}') {
|
|
return ctx.begin();
|
|
}
|
|
|
|
bool t_parsed = false;
|
|
|
|
auto itr = ctx.begin();
|
|
auto buf = fmtbuf.begin();
|
|
|
|
while (*itr != close_brace) {
|
|
if (*itr == delim) {
|
|
if (t_parsed) {
|
|
fmt::throw_format_error("multiple delims encountered");
|
|
}
|
|
t_parsed = true;
|
|
*buf = close_brace;
|
|
auto str = basic_string_view<char_type>(
|
|
fmtbuf.data(), std::distance(fmtbuf.begin(), buf));
|
|
basic_format_parse_context<char_type> subparser(str, 0);
|
|
t_fmtr.parse(subparser);
|
|
buf = fmtbuf.begin();
|
|
} else {
|
|
*buf = *itr;
|
|
++buf;
|
|
}
|
|
++itr;
|
|
}
|
|
|
|
*buf = close_brace;
|
|
auto str = basic_string_view<char_type>(
|
|
fmtbuf.data(), std::distance(fmtbuf.begin(), buf));
|
|
basic_format_parse_context<char_type> subparser(str, 0);
|
|
if (t_parsed) {
|
|
e_fmtr.parse(subparser);
|
|
} else {
|
|
t_fmtr.parse(subparser);
|
|
}
|
|
|
|
ctx.advance_to(itr);
|
|
|
|
return itr;
|
|
}
|
|
|
|
auto format(tl::expected<T, E> const& v, auto& ctx) const {
|
|
if (v) {
|
|
// return fmt::format_to(ctx.out(), "{}", v.value());
|
|
return t_fmtr.format(v.value(), ctx);
|
|
} else {
|
|
return e_fmtr.format(v.error(), ctx);
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif // msgpack_test_utils_4573e6627d8efe78
|