use crate::types::Socket;
#[derive(Clone, Copy, Debug)]
pub struct Sockets {
sockets: [c_ares_sys::ares_socket_t; c_ares_sys::ARES_GETSOCK_MAXNUM],
bitmask: u32,
}
impl Sockets {
pub(super) fn new(
socks: [c_ares_sys::ares_socket_t; c_ares_sys::ARES_GETSOCK_MAXNUM],
bitmask: u32,
) -> Self {
Sockets {
sockets: socks,
bitmask,
}
}
pub fn iter(&self) -> SocketsIter<'_> {
SocketsIter {
next: 0,
sockets: self,
}
}
}
#[derive(Clone, Debug)]
pub struct SocketsIter<'a> {
next: usize,
sockets: &'a Sockets,
}
impl Iterator for SocketsIter<'_> {
type Item = (Socket, bool, bool);
fn next(&mut self) -> Option<Self::Item> {
let index = self.next;
self.next += 1;
if index >= c_ares_sys::ARES_GETSOCK_MAXNUM {
None
} else {
let bit = 1 << index;
let readable = (self.sockets.bitmask & bit) != 0;
let bit = bit << c_ares_sys::ARES_GETSOCK_MAXNUM;
let writable = (self.sockets.bitmask & bit) != 0;
if readable || writable {
let fd = self.sockets.sockets[index];
Some((fd, readable, writable))
} else {
None
}
}
}
}
impl<'a> IntoIterator for &'a Sockets {
type Item = (Socket, bool, bool);
type IntoIter = SocketsIter<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[cfg(test)]
mod tests {
use super::super::Channel;
use super::*;
#[test]
fn sockets_iter_empty() {
let channel = Channel::new().unwrap();
let sockets = channel.sockets();
let mut iter = sockets.iter();
assert!(iter.next().is_none());
}
#[test]
fn sockets_iter_clone() {
let channel = Channel::new().unwrap();
let sockets = channel.sockets();
let iter = sockets.iter();
let _cloned = iter.clone();
}
#[test]
fn sockets_is_send() {
fn assert_send<T: Send>() {}
assert_send::<Sockets>();
}
#[test]
fn sockets_is_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<Sockets>();
}
#[test]
fn sockets_iter_is_send() {
fn assert_send<T: Send>() {}
assert_send::<SocketsIter<'_>>();
}
#[test]
fn sockets_iter_is_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<SocketsIter<'_>>();
}
#[test]
fn sockets_into_iter() {
let channel = Channel::new().unwrap();
let sockets = channel.sockets();
assert_eq!(sockets.into_iter().count(), 0);
}
#[test]
fn sockets_iter_exhausted() {
let channel = Channel::new().unwrap();
let sockets = channel.sockets();
let mut iter = sockets.iter();
while iter.next().is_some() {}
assert!(iter.next().is_none());
assert!(iter.next().is_none());
}
#[test]
fn sockets_debug() {
let channel = Channel::new().unwrap();
let sockets = channel.sockets();
let debug_str = format!("{sockets:?}");
assert!(debug_str.contains("Sockets"));
}
#[test]
fn sockets_iter_debug() {
let channel = Channel::new().unwrap();
let sockets = channel.sockets();
let iter = sockets.iter();
let debug_str = format!("{iter:?}");
assert!(debug_str.contains("SocketsIter"));
}
#[test]
#[allow(clippy::clone_on_copy)]
fn sockets_clone() {
let channel = Channel::new().unwrap();
let sockets = channel.sockets();
let _cloned = sockets.clone();
}
#[test]
fn sockets_copy() {
let channel = Channel::new().unwrap();
let sockets = channel.sockets();
let copied: Sockets = sockets;
let _ = copied;
}
}