use fehler::throws; use std::{ io::{self, Error}, mem::MaybeUninit, }; use tokio::io::unix::AsyncFd; pub struct TunQueue { io: AsyncFd, } impl TunQueue { #[throws] pub fn from_queue(queue: tun::TunQueue) -> Self { Self { io: AsyncFd::new(queue)?, } } pub async fn try_recv(&self, buf: &mut [MaybeUninit]) -> io::Result { loop { let mut guard = self.io.readable().await?; match guard.try_io(|inner| inner.get_ref().recv(buf)) { Ok(result) => return result, Err(..) => continue, } } } }