I am using the pnet crate to parse packets from a pcap file and am attempting to make it faster using rayon to parallelize the process.
The pnet_datalink DataLinkReceiver's next function returns a reference, probably why it doesn't implement the Iterator trait. So I tried to work around it and am having a bit of trouble with the lifetimes.
Here is my code:
extern crate pnet;
use pnet::datalink::DataLinkReceiver;
struct ChannelIterator<'a> {
rx: &'a mut DataLinkReceiver
}
impl<'a> Iterator for ChannelIterator<'a> {
type Item = &'a [u8];
fn next(&mut self) -> Option<&'a [u8]> {
match self.rx.next() {
Ok(pktbuf) => {
return Some(pktbuf);
},
Err(e) => {
return None;
}
}
}
}
and the error message:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main/pcapgrep.rs:74:23
|
74 | match self.rx.next() {
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 73:5...
--> src/main/pcapgrep.rs:73:5
|
73 | / fn next(&mut self) -> Option<&'a [u8]> {
74 | | match self.rx.next() {
75 | | Ok(pktbuf) => {
76 | | return Some(pktbuf);
... |
81 | | }
82 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main/pcapgrep.rs:74:15
|
74 | match self.rx.next() {
| ^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 70:1...
--> src/main/pcapgrep.rs:70:1
|
70 | / impl<'a> Iterator for ChannelIterator<'a> {
71 | | type Item = &'a [u8];
72 | |
73 | | fn next(&mut self) -> Option<&'a [u8]> {
... |
82 | | }
83 | | }
| |_^
note: ...so that expression is assignable (expected std::option::Option<&'a [u8]>, found std::option::Option<&[u8]>)
--> src/main/pcapgrep.rs:76:24
|
76 | return Some(pktbuf);
| ^^^^^^^^^^^^
What I don't understand is that DataLinkReceiver.next() returns a result with a lifetime same as self, or in this case the same lifetime of rx. Since the lifetime of rx is 'a then so should the lifetime of the returned reference in the Result that rx.next() returns.
From how I'm reading the error message it seems that rust is treating the reference of rx as not 'a but as starting from the match statement?