#include #include using namespace boost::ut; namespace { template constexpr std::array make_bytes(Bytes &&...bytes) { return {std::byte(std::forward(bytes))...}; } template struct oversized_array { std::array data; std::size_t size; }; constexpr auto to_bytes_array_oversized(auto const &container) { oversized_array arr; std::copy(std::begin(container), std::end(container), std::begin(arr.data)); arr.size = std::distance(std::begin(container), std::end(container)); return arr; } consteval auto generate_bytes(auto callable) { constexpr auto oversized = to_bytes_array_oversized(callable()); std::array out; std::copy(std::begin(oversized.data), std::next(std::begin(oversized.data), oversized.size), std::begin(out)); return out; } template consteval auto cat(std::array const &a, std::array const &b) { std::array out; std::copy(std::begin(a), std::next(std::begin(a), std::size(a)), std::begin(out)); std::copy(std::begin(b), std::next(std::begin(b), std::size(b)), std::next(std::begin(out), std::size(a))); return out; } constexpr auto from_string_view(std::string_view sv) { std::vector range; range.resize(sv.size()); auto itr = range.begin(); for (auto c : sv) { *itr = std::byte(c); ++itr; } return range; } template constexpr bool wrong_types(auto const& obj) { auto err = tl::make_unexpected(msgpack::error::wrong_type); if (obj.template get() != err) return false; if constexpr (sizeof...(Others)) { return wrong_types(obj); } else { return true; } } template std::ostream &operator<<(std::ostream &os, tl::expected const &exp) { if (exp.has_value()) { os << "Value: '" << *exp << "'"; } else { os << "Error"; } return os; } } suite reader = [] { "read uint32"_test = [] { constexpr auto payload = make_bytes(0xce, 0x01, 0x02, 0x03, 0x09); msgpack::token_reader reader(payload); auto token = reader.read_one(); expect(token && token->type() == msgpack::format::type::unsigned_int); expect(token->get() == tl::make_unexpected(msgpack::error::will_truncate)); expect(token->get() == tl::make_unexpected(msgpack::error::will_truncate)); expect(token->get() == 0x01020309); expect(token->get() == 0x01020309); token = reader.read_one(); expect(token == tl::make_unexpected(msgpack::error::end_of_message)); }; "read str8"_test = [] { constexpr std::string_view sv = "hello d"; constexpr auto payload = cat(make_bytes(0xd9, sv.size()), generate_bytes([sv] { return from_string_view(sv); })); msgpack::token_reader reader(payload); auto token = reader.read_one(); expect(token && token->type() == msgpack::format::type::string); expect(token->get() == sv); token = reader.read_one(); expect(token == tl::make_unexpected(msgpack::error::end_of_message)); }; };