use std::iter::FusedIterator;
use std::ops::Range;
use std::os::fd::RawFd;
use nix::unistd::close;
use crate::Error;
use crate::fd::Fd;
#[must_use]
#[derive(Debug)]
pub struct ListenFds(Range<RawFd>);
impl ListenFds {
pub(crate) const START: RawFd = 3;
#[inline]
pub const unsafe fn new(num: u32) -> Self {
Self(Range { start: Self::START, end: Self::START + num as RawFd })
}
}
impl Drop for ListenFds {
fn drop(&mut self) {
for fd in &mut self.0 {
let res = close(fd);
debug_assert!(res.is_ok());
}
}
}
impl Iterator for ListenFds {
type Item = Result<Fd, Error>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|fd| unsafe { Fd::try_from(fd) })
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl DoubleEndedIterator for ListenFds {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|fd| unsafe { Fd::try_from(fd) })
}
}
impl ExactSizeIterator for ListenFds {}
impl FusedIterator for ListenFds {}