//----------------------------------------------------------------------------- // ___ __ _ _ // / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ // / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / // / ___/ (_| | | \__ \ __/ /__| | | | | < // \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . // //----------------------------------------------------------------------------- // 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 #include namespace parselink { logging::logger& get_logger(); } namespace msgpack { template struct unpacker_adapter { static constexpr auto unpack(auto& unpacker) noexcept -> tl::expected { auto verify_name = unpacker.template unpack(); 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(); if (!mapsize) { return tl::make_unexpected(error::wrong_type); } else if (mapsize->count != boost::pfr::tuple_size_v) { return tl::make_unexpected(error::wrong_type); } return M{}; } }; } // namespace msgpack namespace parselink { namespace proto { //////////////////////////////////////////////////////////////////////////////// // Default parse template instantiation -- unsupported message. //////////////////////////////////////////////////////////////////////////////// template tl::expected parse(std::span data) noexcept { return tl::make_unexpected(error::unsupported); } //////////////////////////////////////////////////////////////////////////////// // Currently-implemented message types. //////////////////////////////////////////////////////////////////////////////// #define PARSELINK_PROTO_SUPPORTED_MESSAGE(msgtype) \ tl::expected parse_##msgtype( \ std::span data) noexcept; \ template <> \ constexpr tl::expected parse( \ std::span 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