@@ -29,6 +29,8 @@ pub struct RecvPacketBatch {
2929 pub stride : usize ,
3030 pub len : usize ,
3131 pub transport : Transport ,
32+
33+ offset : usize ,
3234}
3335
3436impl RecvPacketBatch {
@@ -38,42 +40,16 @@ impl RecvPacketBatch {
3840 & self . buf
3941 }
4042
41- pub fn iter ( & self ) -> RecvPacketBatchIter < ' _ > {
42- RecvPacketBatchIter {
43- batch : self ,
44- offset : 0 ,
45- }
46- }
47- }
48-
49- impl < ' a > IntoIterator for & ' a RecvPacketBatch {
50- type Item = & ' a [ u8 ] ;
51- type IntoIter = RecvPacketBatchIter < ' a > ;
52-
53- fn into_iter ( self ) -> Self :: IntoIter {
54- self . iter ( )
55- }
56- }
57-
58- pub struct RecvPacketBatchIter < ' a > {
59- batch : & ' a RecvPacketBatch ,
60- offset : usize ,
61- }
62-
63- impl < ' a > Iterator for RecvPacketBatchIter < ' a > {
64- type Item = & ' a [ u8 ] ;
65-
66- fn next ( & mut self ) -> Option < Self :: Item > {
67- assert ! (
68- self . batch. stride != 0 ,
69- "stride must not be zero in iteration"
70- ) ;
71- let tail = self . batch . len . min ( self . offset + self . batch . stride ) ;
43+ // https://stackoverflow.com/questions/68606470/how-to-return-a-reference-when-implementing-an-iterator
44+ // GAT is not stabilized, so it's not possible to return a reference in an iterator yet.
45+ pub fn next_packet ( & mut self ) -> Option < & [ u8 ] > {
46+ assert ! ( self . stride != 0 , "stride must not be zero in iteration" ) ;
47+ let tail = self . len . min ( self . offset + self . stride ) ;
7248 if self . offset >= tail {
7349 return None ;
7450 }
7551
76- let buf = & self . batch . buf [ self . offset ..tail] ;
52+ let buf = & self . buf [ self . offset ..tail] ;
7753 self . offset = tail;
7854 Some ( buf)
7955 }
@@ -201,38 +177,38 @@ mod tests {
201177
202178 #[ test]
203179 fn recv_packet_batch_iter_yields_multiple_segments_without_off_by_one ( ) {
204- let batch = RecvPacketBatch {
180+ let mut batch = RecvPacketBatch {
205181 src : test_addr ( ) ,
206182 dst : test_addr ( ) ,
207183 buf : ( 0u8 ..20 ) . collect ( ) ,
208184 stride : 6 ,
209185 len : 20 ,
210186 transport : Transport :: Udp ( UdpMode :: Scalar ) ,
187+ offset : 0 ,
211188 } ;
212189
213- let chunks: Vec < & [ u8 ] > = batch. iter ( ) . collect ( ) ;
214- assert_eq ! ( chunks. len( ) , 4 ) ;
215- assert_eq ! ( chunks[ 0 ] , & [ 0 , 1 , 2 , 3 , 4 , 5 ] ) ;
216- assert_eq ! ( chunks[ 1 ] , & [ 6 , 7 , 8 , 9 , 10 , 11 ] ) ;
217- assert_eq ! ( chunks[ 2 ] , & [ 12 , 13 , 14 , 15 , 16 , 17 ] ) ;
218- assert_eq ! ( chunks[ 3 ] , & [ 18 , 19 ] ) ;
190+ assert_eq ! ( batch. next_packet( ) , Some ( & [ 0 , 1 , 2 , 3 , 4 , 5 ] [ ..] ) ) ;
191+ assert_eq ! ( batch. next_packet( ) , Some ( & [ 6 , 7 , 8 , 9 , 10 , 11 ] [ ..] ) ) ;
192+ assert_eq ! ( batch. next_packet( ) , Some ( & [ 12 , 13 , 14 , 15 , 16 , 17 ] [ ..] ) ) ;
193+ assert_eq ! ( batch. next_packet( ) , Some ( & [ 18 , 19 ] [ ..] ) ) ;
194+ assert_eq ! ( batch. next_packet( ) , None ) ;
219195 }
220196
221197 #[ test]
222198 fn recv_packet_batch_iter_yields_multiple_segments_with_exact_len ( ) {
223- let batch = RecvPacketBatch {
199+ let mut batch = RecvPacketBatch {
224200 src : test_addr ( ) ,
225201 dst : test_addr ( ) ,
226202 buf : ( 0u8 ..20 ) . collect ( ) ,
227203 stride : 6 ,
228204 len : 18 ,
229205 transport : Transport :: Udp ( UdpMode :: Scalar ) ,
206+ offset : 0 ,
230207 } ;
231208
232- let chunks: Vec < & [ u8 ] > = batch. iter ( ) . collect ( ) ;
233- assert_eq ! ( chunks. len( ) , 3 ) ;
234- assert_eq ! ( chunks[ 0 ] , & [ 0 , 1 , 2 , 3 , 4 , 5 ] ) ;
235- assert_eq ! ( chunks[ 1 ] , & [ 6 , 7 , 8 , 9 , 10 , 11 ] ) ;
236- assert_eq ! ( chunks[ 2 ] , & [ 12 , 13 , 14 , 15 , 16 , 17 ] ) ;
209+ assert_eq ! ( batch. next_packet( ) , Some ( & [ 0 , 1 , 2 , 3 , 4 , 5 ] [ ..] ) ) ;
210+ assert_eq ! ( batch. next_packet( ) , Some ( & [ 6 , 7 , 8 , 9 , 10 , 11 ] [ ..] ) ) ;
211+ assert_eq ! ( batch. next_packet( ) , Some ( & [ 12 , 13 , 14 , 15 , 16 , 17 ] [ ..] ) ) ;
212+ assert_eq ! ( batch. next_packet( ) , None ) ;
237213 }
238214}
0 commit comments