2017-01-11 12:05:41 +08:00
|
|
|
use managed::ManagedSlice;
|
|
|
|
use core::slice;
|
|
|
|
|
|
|
|
use super::Socket;
|
|
|
|
|
|
|
|
/// A handle, identifying a socket in a set.
|
2017-01-12 12:09:41 +08:00
|
|
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
2017-01-11 12:05:41 +08:00
|
|
|
pub struct Handle {
|
|
|
|
index: usize
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An extensible set of sockets, with stable numeric identifiers.
|
2017-01-12 12:28:34 +08:00
|
|
|
#[derive(Debug)]
|
2017-01-11 12:05:41 +08:00
|
|
|
pub struct Set<'a, 'b: 'a, 'c: 'a + 'b> {
|
|
|
|
sockets: ManagedSlice<'a, Option<Socket<'b, 'c>>>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'b: 'a, 'c: 'a + 'b> Set<'a, 'b, 'c> {
|
|
|
|
/// Create a socket set using the provided storage.
|
|
|
|
pub fn new<SocketsT>(sockets: SocketsT) -> Set<'a, 'b, 'c>
|
|
|
|
where SocketsT: Into<ManagedSlice<'a, Option<Socket<'b, 'c>>>> {
|
|
|
|
let sockets = sockets.into();
|
|
|
|
Set {
|
|
|
|
sockets: sockets
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Add a socket to the set, and return its handle.
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
/// This function panics if the storage is fixed-size (not a `Vec`) and is full.
|
2017-01-17 07:35:21 +08:00
|
|
|
pub fn add(&mut self, mut socket: Socket<'b, 'c>) -> Handle {
|
2017-01-11 12:05:41 +08:00
|
|
|
for (index, slot) in self.sockets.iter_mut().enumerate() {
|
|
|
|
if slot.is_none() {
|
2017-01-17 07:35:21 +08:00
|
|
|
socket.set_debug_id(index);
|
2017-01-11 12:05:41 +08:00
|
|
|
*slot = Some(socket);
|
|
|
|
return Handle { index: index }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
match self.sockets {
|
|
|
|
ManagedSlice::Borrowed(_) => {
|
|
|
|
panic!("adding a socket to a full SocketSet")
|
|
|
|
}
|
|
|
|
ManagedSlice::Owned(ref mut sockets) => {
|
2017-01-17 07:35:21 +08:00
|
|
|
let index = sockets.len();
|
|
|
|
socket.set_debug_id(index);
|
2017-01-11 12:05:41 +08:00
|
|
|
sockets.push(Some(socket));
|
2017-01-17 07:35:21 +08:00
|
|
|
Handle { index: index }
|
2017-01-11 12:05:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get a socket from the set by its handle.
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
/// This function may panic if the handle does not belong to this socket set.
|
2017-01-12 12:09:41 +08:00
|
|
|
pub fn get(&self, handle: Handle) -> &Socket<'b, 'c> {
|
2017-01-11 12:05:41 +08:00
|
|
|
self.sockets[handle.index]
|
|
|
|
.as_ref()
|
2017-01-12 12:09:41 +08:00
|
|
|
.expect("handle does not refer to a valid socket")
|
2017-01-11 12:05:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get a socket from the set by its handle, as mutable.
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
/// This function may panic if the handle does not belong to this socket set.
|
2017-01-12 12:09:41 +08:00
|
|
|
pub fn get_mut(&mut self, handle: Handle) -> &mut Socket<'b, 'c> {
|
2017-01-11 12:05:41 +08:00
|
|
|
self.sockets[handle.index]
|
|
|
|
.as_mut()
|
2017-01-12 12:09:41 +08:00
|
|
|
.expect("handle does not refer to a valid socket")
|
2017-01-11 12:05:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Remove a socket from the set, without changing its state.
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
/// This function may panic if the handle does not belong to this socket set.
|
|
|
|
pub fn remove(&mut self, handle: Handle) {
|
|
|
|
assert!(self.sockets[handle.index].is_some());
|
|
|
|
self.sockets[handle.index] = None
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Iterate every socket in this set.
|
|
|
|
pub fn iter<'d>(&'d self) -> Iter<'d, 'b, 'c> {
|
|
|
|
Iter { lower: self.sockets.iter() }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Iterate every socket in this set, as mutable.
|
|
|
|
pub fn iter_mut<'d>(&'d mut self) -> IterMut<'d, 'b, 'c> {
|
|
|
|
IterMut { lower: self.sockets.iter_mut() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Immutable socket set iterator.
|
|
|
|
///
|
|
|
|
/// This struct is created by the [iter](struct.SocketSet.html#method.iter)
|
|
|
|
/// on [socket sets](struct.SocketSet.html).
|
|
|
|
pub struct Iter<'a, 'b: 'a, 'c: 'a + 'b> {
|
|
|
|
lower: slice::Iter<'a, Option<Socket<'b, 'c>>>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'b: 'a, 'c: 'a + 'b> Iterator for Iter<'a, 'b, 'c> {
|
|
|
|
type Item = &'a Socket<'b, 'c>;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
while let Some(socket_opt) = self.lower.next() {
|
|
|
|
if let Some(socket) = socket_opt.as_ref() {
|
|
|
|
return Some(socket)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Mutable socket set iterator.
|
|
|
|
///
|
|
|
|
/// This struct is created by the [iter_mut](struct.SocketSet.html#method.iter_mut)
|
|
|
|
/// on [socket sets](struct.SocketSet.html).
|
|
|
|
pub struct IterMut<'a, 'b: 'a, 'c: 'a + 'b> {
|
|
|
|
lower: slice::IterMut<'a, Option<Socket<'b, 'c>>>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'b: 'a, 'c: 'a + 'b> Iterator for IterMut<'a, 'b, 'c> {
|
|
|
|
type Item = &'a mut Socket<'b, 'c>;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
while let Some(socket_opt) = self.lower.next() {
|
|
|
|
if let Some(socket) = socket_opt.as_mut() {
|
|
|
|
return Some(socket)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|