1use std::{io::Cursor, marker::PhantomData};
4
5use log::trace;
6
7use crate::{
8 FromBytes, FromBytesWithInput, Size, consts::nl::NlType, err::SocketError, nl::Nlmsghdr,
9};
10
11pub struct NlBufferIter<T, P, B> {
14 buffer: Cursor<B>,
15 next_is_none: bool,
16 data: PhantomData<(T, P)>,
17}
18
19impl<T, P, B> NlBufferIter<T, P, B>
20where
21 B: AsRef<[u8]>,
22{
23 #[cfg(any(feature = "sync", feature = "async"))]
24 pub(crate) fn new(buffer: Cursor<B>) -> Self {
25 NlBufferIter {
26 buffer,
27 next_is_none: false,
28 data: PhantomData,
29 }
30 }
31
32 pub fn next_typed<TT, PP>(&mut self) -> Option<Result<Nlmsghdr<TT, PP>, SocketError>>
35 where
36 TT: NlType,
37 PP: Size + FromBytesWithInput<Input = usize>,
38 {
39 if self.buffer.position() as usize == self.buffer.get_ref().as_ref().len()
40 || self.next_is_none
41 {
42 None
43 } else {
44 match Nlmsghdr::from_bytes(&mut self.buffer).map_err(SocketError::from) {
45 Ok(msg) => {
46 trace!("Message received: {msg:?}");
47 Some(Ok(msg))
48 }
49 Err(e) => {
50 self.next_is_none = true;
51 Some(Err(e))
52 }
53 }
54 }
55 }
56}
57
58impl<T, P, B> Iterator for NlBufferIter<T, P, B>
59where
60 B: AsRef<[u8]>,
61 T: NlType,
62 P: Size + FromBytesWithInput<Input = usize>,
63{
64 type Item = Result<Nlmsghdr<T, P>, SocketError>;
65
66 fn next(&mut self) -> Option<Self::Item> {
67 self.next_typed::<T, P>()
68 }
69}