rust-pcap / pcap

Rust language pcap library
Apache License 2.0
610 stars 138 forks source link

Capture mutably borrowed during loop #194

Closed gmacon closed 2 years ago

gmacon commented 2 years ago

I have code that boils down to

    fn compile_test(mut capture: Capture<Offline>, output: &Path) -> Result<(), Error> {
        while let Ok(packet) = capture.next() {
            let mut savefile = capture.savefile(output)?;
            savefile.write(&packet);
            savefile.flush()?;
        }
        Ok(())
    }

which fails with this error:

error[E0502]: cannot borrow `capture` as immutable because it is also borrowed as mutable
   --> tests/lib.rs:347:32
    |
346 |         while let Ok(packet) = capture.next() {
    |                                ------- mutable borrow occurs here
347 |             let mut savefile = capture.savefile(output)?;
    |                                ^^^^^^^ immutable borrow occurs here
348 |             savefile.write(&packet);
    |                            ------- mutable borrow later used here

I tried using the same trick as streaming_iterator, which is splitting next(&mut self) -> Result<Packet, Error> into advance(&mut self) and get(&self) -> Result<Packet, Error>, but that didn't help.

Edited to add: my attempt is at https://github.com/gmacon/pcap/tree/shared-borrow-next

Does anyone know a way of telling the Rust compiler that the result of next is a shared borrow of self instead of a mutable borrow?

If I should ask this question in a different forum, please let me know.

gmacon commented 2 years ago

I've now found Limits of Lifetimes in the 'Nomicon, which implies that what I'm asking for here is impossible without changing the API. After thinking about it, I've realized that this doesn't cause a problem for streaming_iterator because there are no additional useful methods to call on a StreamingIterator, so you can't notice that you can't call anything else.