Search code examples
rustpcap

`variable` was mutably borrowed here in the previous iteration of the loop


I'm fairly new to Rust, and I've been trying to work through an error in my code.

The code below compiles. However, if I uncomment out the line to add a packet to my buffer, it throws the error:

`interface` was mutably borrowed here in the previous iteration of the loop

How? It's not related at all to the packet at that point. I thought I was beginning to grasp references and memory management concepts, but this has me second guessing everything...

        let mut buffer: VecDeque<pcap::Packet> = VecDeque::with_capacity(1000);
        while let Ok(packet) = interface.next_packet() {
            if start_time.is_none() {
                start_time = Some(Instant::now());
            }

            let buf_packet = packet.to_owned();

            // buffer.push_back(buf_packet);

            let elapsed = start_time.unwrap().elapsed();
            if elapsed >= time_limit {
                break;
            }
        }

Solution

  • Packet has no owned variant. to_owned() is from the blanket ToOwned implementation in the standard library, which is implemented for anything that implements Clone. Weirdly, this type implements Clone but not Copy.

    Anyway, Packet just holds two references. Cloning copies those references, so this doesn't actually do anything meaningful with regards to the borrows or their lifetimes.

    Instead, consider implementing your own "owned packet" type that owns its own data:

    struct OwnedPacket {
        pub header: PacketHeader,
        pub data: Vec<u8>,
    }
    
    impl<'a> From<Packet<'a>> for OwnedPacket {
        fn from(other: Packet<'a>) -> Self {
            Self {
                header: *other.header,
                data: other.data.into(),
            }
        }
    }
    

    Now you can change your deque to VecDeque<OwnedPacket> and call packet.into() when pushing the packet to perform the copy.