From 09c1e987f6ddfdefb26b6a5f359363303720d5fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sat, 26 Aug 2023 21:38:36 +0200 Subject: Network: header item as variant of per-header-type structs --- src/network/protocol.cpp | 130 ++++++++++++++++------------------------------- src/network/protocol.h | 28 ++++++---- 2 files changed, 61 insertions(+), 97 deletions(-) (limited to 'src/network') diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index f38267f..ede7023 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -9,11 +9,12 @@ #include #include +using std::get_if; using std::holds_alternative; using std::move; using std::nullopt; -using std::runtime_error; using std::scoped_lock; +using std::visit; namespace erebos { @@ -327,21 +328,16 @@ void NetworkProtocol::Connection::trySendOutQueue() /* Header */ /******************************************************************************/ -bool NetworkProtocol::Header::Item::operator==(const Item & other) const +bool operator==(const NetworkProtocol::Header::Item & left, + const NetworkProtocol::Header::Item & right) { - if (type != other.type) + if (left.index() != right.index()) return false; - if (value.index() != other.value.index()) - return false; - - if (holds_alternative(value)) - return std::get(value) == std::get(other.value); - - if (holds_alternative(value)) - return std::get(value) == std::get(other.value); - - throw runtime_error("unhandled network header item type"); + return visit([&](auto && arg) { + using T = std::decay_t; + return arg.value == std::get(right).value; + }, left); } optional NetworkProtocol::Header::load(const PartialRef & ref) @@ -359,58 +355,31 @@ optional NetworkProtocol::Header::load(const PartialObj for (const auto & item : rec->items()) { if (item.name == "ACK") { if (auto ref = item.asRef()) - items.emplace_back(Item { - .type = Type::Acknowledged, - .value = ref->digest(), - }); + items.emplace_back(Acknowledged { ref->digest() }); } else if (item.name == "REQ") { if (auto ref = item.asRef()) - items.emplace_back(Item { - .type = Type::DataRequest, - .value = ref->digest(), - }); + items.emplace_back(DataRequest { ref->digest() }); } else if (item.name == "RSP") { if (auto ref = item.asRef()) - items.emplace_back(Item { - .type = Type::DataResponse, - .value = ref->digest(), - }); + items.emplace_back(DataResponse { ref->digest() }); } else if (item.name == "ANN") { if (auto ref = item.asRef()) - items.emplace_back(Item { - .type = Type::AnnounceSelf, - .value = ref->digest(), - }); + items.emplace_back(AnnounceSelf { ref->digest() }); } else if (item.name == "ANU") { if (auto ref = item.asRef()) - items.emplace_back(Item { - .type = Type::AnnounceUpdate, - .value = ref->digest(), - }); + items.emplace_back(AnnounceUpdate { ref->digest() }); } else if (item.name == "CRQ") { if (auto ref = item.asRef()) - items.emplace_back(Item { - .type = Type::ChannelRequest, - .value = ref->digest(), - }); + items.emplace_back(ChannelRequest { ref->digest() }); } else if (item.name == "CAC") { if (auto ref = item.asRef()) - items.emplace_back(Item { - .type = Type::ChannelAccept, - .value = ref->digest(), - }); + items.emplace_back(ChannelAccept { ref->digest() }); } else if (item.name == "STP") { if (auto val = item.asUUID()) - items.emplace_back(Item { - .type = Type::ServiceType, - .value = *val, - }); + items.emplace_back(ServiceType { *val }); } else if (item.name == "SRF") { if (auto ref = item.asRef()) - items.emplace_back(Item { - .type = Type::ServiceRef, - .value = ref->digest(), - }); + items.emplace_back(ServiceRef { ref->digest() }); } } @@ -422,43 +391,32 @@ PartialObject NetworkProtocol::Header::toObject(const PartialStorage & st) const vector ritems; for (const auto & item : items) { - switch (item.type) { - case Type::Acknowledged: - ritems.emplace_back("ACK", st.ref(std::get(item.value))); - break; - - case Type::DataRequest: - ritems.emplace_back("REQ", st.ref(std::get(item.value))); - break; - - case Type::DataResponse: - ritems.emplace_back("RSP", st.ref(std::get(item.value))); - break; - - case Type::AnnounceSelf: - ritems.emplace_back("ANN", st.ref(std::get(item.value))); - break; - - case Type::AnnounceUpdate: - ritems.emplace_back("ANU", st.ref(std::get(item.value))); - break; - - case Type::ChannelRequest: - ritems.emplace_back("CRQ", st.ref(std::get(item.value))); - break; - - case Type::ChannelAccept: - ritems.emplace_back("CAC", st.ref(std::get(item.value))); - break; - - case Type::ServiceType: - ritems.emplace_back("STP", std::get(item.value)); - break; - - case Type::ServiceRef: - ritems.emplace_back("SRF", st.ref(std::get(item.value))); - break; - } + if (const auto * ptr = get_if(&item)) + ritems.emplace_back("ACK", st.ref(ptr->value)); + + else if (const auto * ptr = get_if(&item)) + ritems.emplace_back("REQ", st.ref(ptr->value)); + + else if (const auto * ptr = get_if(&item)) + ritems.emplace_back("RSP", st.ref(ptr->value)); + + else if (const auto * ptr = get_if(&item)) + ritems.emplace_back("ANN", st.ref(ptr->value)); + + else if (const auto * ptr = get_if(&item)) + ritems.emplace_back("ANU", st.ref(ptr->value)); + + else if (const auto * ptr = get_if(&item)) + ritems.emplace_back("CRQ", st.ref(ptr->value)); + + else if (const auto * ptr = get_if(&item)) + ritems.emplace_back("CAC", st.ref(ptr->value)); + + else if (const auto * ptr = get_if(&item)) + ritems.emplace_back("STP", ptr->value); + + else if (const auto * ptr = get_if(&item)) + ritems.emplace_back("SRF", st.ref(ptr->value)); } return PartialObject(PartialRecord(std::move(ritems))); diff --git a/src/network/protocol.h b/src/network/protocol.h index c5803ce..df29c05 100644 --- a/src/network/protocol.h +++ b/src/network/protocol.h @@ -106,7 +106,17 @@ struct NetworkProtocol::ConnectionReadReady { Connection::Id id; }; struct NetworkProtocol::Header { - enum class Type { + struct Acknowledged { Digest value; }; + struct DataRequest { Digest value; }; + struct DataResponse { Digest value; }; + struct AnnounceSelf { Digest value; }; + struct AnnounceUpdate { Digest value; }; + struct ChannelRequest { Digest value; }; + struct ChannelAccept { Digest value; }; + struct ServiceType { UUID value; }; + struct ServiceRef { Digest value; }; + + using Item = variant< Acknowledged, DataRequest, DataResponse, @@ -115,16 +125,7 @@ struct NetworkProtocol::Header ChannelRequest, ChannelAccept, ServiceType, - ServiceRef, - }; - - struct Item { - const Type type; - const variant value; - - bool operator==(const Item &) const; - bool operator!=(const Item & other) const { return !(*this == other); } - }; + ServiceRef>; Header(const vector & items): items(items) {} static optional
load(const PartialRef &); @@ -134,6 +135,11 @@ struct NetworkProtocol::Header const vector items; }; +bool operator==(const NetworkProtocol::Header::Item &, const NetworkProtocol::Header::Item &); +inline bool operator!=(const NetworkProtocol::Header::Item & left, + const NetworkProtocol::Header::Item & right) +{ return not (left == right); } + class ReplyBuilder { public: -- cgit v1.2.3