Is there a cleaner way of writing this subroutine?

It is possible that there exists a key of type u64 within either one of the two hashmaps contained within self. The same key cannot contain an entry in both hashmaps. I run a match against a tuple as such:

    fn start_send(&mut self, item: Self::SinkItem) -> Result<AsyncSink<Self::SinkItem>, Self::SinkError> {
        let eid_oid = item.get_header().oid_eid.get();

        if eid_oid != 0 {
            match (self.object_expectancies.get_mut(&eid_oid), self.singleton_expectancies.get_mut(&eid_oid)) {
                (Some(exp), None) => {
                    exp.deliver_packet(item).or_else(|_| {
                        item.stage = PacketStage::NeedsDelete
                    });
                },

                (None, Some(exp)) => {
                    exp.deliver_packet(item).or_else(|_| {
                        item.stage = PacketStage::NeedsDelete
                    });
                },

                _ => {
                        /// a packet was sent to this node, but localhost did not expect this eid_oid. TODO: implement packet forwarding system
                }
            }
        } else {
            // This implies a packet was sent to this node without an expectation of being responded to. Enqueue it for stage 3
            self.fifo.push_back(item);
        }

        Ok(AsyncSink::Ready)
    }

Not sure if this is really cleaner, but it avoids the double lookup when not necessary:

    if eid_oid != 0 {
        self.object_expectancies
            .get_mut(&eid_oid)
            .or_else(|| self.singleton_expectancies.get_mut(&eid_oid))
            .map(|e| {
                e.deliver_packet(item)
                    .or_else(|_| item.stage = PacketStage::NeedsDelete)
            })
            .unwrap_or_else(|| {
                // TODO...
            });
    }

Note this is just a rough sketch and probably has at least some warnings (a working playground link would have helped :slight_smile: ), but it shows the idea.

1 Like