96 lines
3.3 KiB
C++
96 lines
3.3 KiB
C++
//-----------------------------------------------------------------------------
|
|
// ___ __ _ _
|
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// Author: Kurt Sassenrath
|
|
// Module: Proto
|
|
//
|
|
// Parser for extracting messages from msgpack.
|
|
//
|
|
// Note: Eventually, it would be nice to automatically generate the parser for
|
|
// message structures. Definitions below are templated to allow for this.
|
|
//
|
|
// Copyright (c) 2023 Kurt Sassenrath.
|
|
//
|
|
// License TBD.
|
|
//-----------------------------------------------------------------------------
|
|
#ifndef parselink_proto_parser_ad351d41fe4c72dd
|
|
#define parselink_proto_parser_ad351d41fe4c72dd
|
|
|
|
#include "parselink/logging.h"
|
|
#include "parselink/proto/error.h"
|
|
#include "parselink/proto/message.h"
|
|
|
|
#include "parselink/msgpack/core/unpacker.h"
|
|
|
|
#include <tl/expected.hpp>
|
|
#include <boost/pfr.hpp>
|
|
|
|
namespace parselink {
|
|
logging::logger& get_logger();
|
|
}
|
|
|
|
namespace msgpack {
|
|
|
|
template <parselink::proto::message_type M>
|
|
struct unpacker_adapter<M> {
|
|
static constexpr auto unpack(auto& unpacker) noexcept
|
|
-> tl::expected<M, error> {
|
|
auto verify_name = unpacker.template unpack<std::string_view>();
|
|
|
|
if (!verify_name || verify_name != M::message_name()) {
|
|
fmt::print("{} {}\n", verify_name, M::message_name());
|
|
return tl::make_unexpected(error::wrong_type);
|
|
}
|
|
|
|
auto mapsize = unpacker.template unpack<msgpack::map_desc>();
|
|
|
|
if (!mapsize) {
|
|
return tl::make_unexpected(error::wrong_type);
|
|
} else if (mapsize->count != boost::pfr::tuple_size_v<M>) {
|
|
return tl::make_unexpected(error::wrong_type);
|
|
}
|
|
|
|
return M{};
|
|
}
|
|
};
|
|
|
|
} // namespace msgpack
|
|
|
|
namespace parselink {
|
|
namespace proto {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Default parse template instantiation -- unsupported message.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template <message_type M>
|
|
tl::expected<M, error> parse(std::span<std::byte const> data) noexcept {
|
|
return tl::make_unexpected(error::unsupported);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Currently-implemented message types.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define PARSELINK_PROTO_SUPPORTED_MESSAGE(msgtype) \
|
|
tl::expected<msgtype, error> parse_##msgtype( \
|
|
std::span<std::byte const> data) noexcept; \
|
|
template <> \
|
|
constexpr tl::expected<msgtype, error> parse( \
|
|
std::span<std::byte const> data) noexcept { \
|
|
return parse_##msgtype(data); \
|
|
}
|
|
|
|
PARSELINK_PROTO_SUPPORTED_MESSAGE(connect_message);
|
|
|
|
#undef PARSELINK_PROTO_SUPPORTED_MESSAGE
|
|
|
|
} // namespace proto
|
|
} // namespace parselink
|
|
|
|
#endif // parselink_proto_parser_ad351d41fe4c72dd
|