use super::*;
use std::io;
use std::ops::{Index, IndexMut, RangeBounds};
use std::slice::{Iter, IterMut, SliceIndex};
use std::vec::{Drain, IntoIter};
pub struct Tun {
queues: Vec<Queue>,
name: String,
}
impl Tun {
pub fn new(name: &str, num_queues: usize) -> Result<Self> {
if num_queues < 1 {
return Err(Error::InvalidNumQueues);
}
let (queues, name) = new_queues(name, num_queues)?;
Ok(Self { queues, name })
}
#[inline]
pub fn name(&self) -> &str {
self.name.as_str()
}
#[inline]
pub fn get<I>(&self, index: I) -> Option<&Queue>
where
I: SliceIndex<[Queue], Output = Queue>,
{
self.queues.get(index)
}
#[inline]
pub fn get_mut<I>(&mut self, index: I) -> Option<&mut Queue>
where
I: SliceIndex<[Queue], Output = Queue>,
{
self.queues.get_mut(index)
}
pub fn close(&mut self) -> Result<()> {
for mut queue in self.drain(..) {
queue.close()?;
}
Ok(())
}
#[inline]
pub fn drain<R>(&mut self, range: R) -> Drain<Queue>
where
R: RangeBounds<usize>,
{
self.queues.drain(range)
}
#[inline]
pub fn iter(&self) -> Iter<Queue> {
self.queues.iter()
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<Queue> {
self.queues.iter_mut()
}
pub fn send_via(&self, queue: usize, datagram: &[u8]) -> io::Result<usize> {
self.get(queue)
.ok_or_else(|| Error::from(queue).into_io())?
.send(datagram)
}
pub fn recv_via(&self, queue: usize, datagram: &mut [u8]) -> io::Result<usize> {
self.get(queue)
.ok_or_else(|| Error::from(queue).into_io())?
.recv(datagram)
}
}
impl IntoIterator for Tun {
type Item = Queue;
type IntoIter = IntoIter<Queue>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.queues.into_iter()
}
}
impl Index<usize> for Tun {
type Output = Queue;
#[inline]
fn index(&self, index: usize) -> &Queue {
self.queues.index(index)
}
}
impl IndexMut<usize> for Tun {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut Queue {
self.queues.index_mut(index)
}
}