76 lines
2.2 KiB
C++
76 lines
2.2 KiB
C++
//-----------------------------------------------------------------------------
|
|
// ___ __ _ _
|
|
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
|
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
|
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
|
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// Author: Kurt Sassenrath
|
|
// Module: Proto
|
|
//
|
|
// Parser implementations for various msgpack messages.
|
|
//
|
|
// Copyright (c) 2023 Kurt Sassenrath.
|
|
//
|
|
// License TBD.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "parselink/proto/parser.h"
|
|
#include "parselink/logging.h"
|
|
|
|
#include "parselink/msgpack/core/unpacker.h"
|
|
|
|
namespace parselink {
|
|
|
|
namespace {
|
|
logging::logger logger{"parser"};
|
|
}
|
|
|
|
namespace proto {
|
|
|
|
namespace {
|
|
|
|
constexpr auto assign(auto& param, msgpack::unpacker& unpacker) noexcept
|
|
-> tl::expected<void, error> {
|
|
auto do_assign = [¶m](auto&& v) { param = v; };
|
|
return unpacker.unpack<std::decay_t<decltype(param)>>()
|
|
.map(do_assign)
|
|
.map_error([](auto) { return error::bad_data; });
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
tl::expected<connect_message, error> parse_connect_message(
|
|
std::span<std::byte const> data) noexcept {
|
|
msgpack::unpacker unpacker(data);
|
|
connect_message msg;
|
|
|
|
constexpr static tl::unexpected<error> bad_data(error::bad_data);
|
|
|
|
auto type = unpacker.unpack<std::string_view>();
|
|
if (!type || type != connect_message::name()) return bad_data;
|
|
|
|
auto entries = unpacker.unpack<msgpack::map_desc>();
|
|
if (!entries) return bad_data;
|
|
|
|
for (auto i = entries->count; i != 0; --i) {
|
|
auto key = unpacker.unpack<std::string_view>();
|
|
if (!key) return bad_data;
|
|
if (key == "version") {
|
|
if (auto val = assign(msg.version, unpacker)) continue;
|
|
} else if (key == "user_id") {
|
|
if (auto val = assign(msg.user_id, unpacker)) continue;
|
|
}
|
|
logger.debug("Unknown key: {}", *key);
|
|
return bad_data;
|
|
}
|
|
|
|
return msg;
|
|
}
|
|
|
|
} // namespace proto
|
|
} // namespace parselink
|
|
|
|
parselink::logging::logger& parselink::get_logger() { return logger; }
|