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 ++++++++++++++++------------------------------- 1 file changed, 44 insertions(+), 86 deletions(-) (limited to 'src/network/protocol.cpp') 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))); -- cgit v1.2.3