smoltcp/iface/
socket_set.rsuse core::fmt;
use managed::ManagedSlice;
use super::socket_meta::Meta;
use crate::socket::{AnySocket, Socket};
#[derive(Debug, Default)]
pub struct SocketStorage<'a> {
inner: Option<Item<'a>>,
}
impl<'a> SocketStorage<'a> {
pub const EMPTY: Self = Self { inner: None };
}
#[derive(Debug)]
pub(crate) struct Item<'a> {
pub(crate) meta: Meta,
pub(crate) socket: Socket<'a>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct SocketHandle(usize);
impl fmt::Display for SocketHandle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "#{}", self.0)
}
}
#[derive(Debug)]
pub struct SocketSet<'a> {
sockets: ManagedSlice<'a, SocketStorage<'a>>,
}
impl<'a> SocketSet<'a> {
pub fn new<SocketsT>(sockets: SocketsT) -> SocketSet<'a>
where
SocketsT: Into<ManagedSlice<'a, SocketStorage<'a>>>,
{
let sockets = sockets.into();
SocketSet { sockets }
}
pub fn add<T: AnySocket<'a>>(&mut self, socket: T) -> SocketHandle {
fn put<'a>(index: usize, slot: &mut SocketStorage<'a>, socket: Socket<'a>) -> SocketHandle {
net_trace!("[{}]: adding", index);
let handle = SocketHandle(index);
let mut meta = Meta::default();
meta.handle = handle;
*slot = SocketStorage {
inner: Some(Item { meta, socket }),
};
handle
}
let socket = socket.upcast();
for (index, slot) in self.sockets.iter_mut().enumerate() {
if slot.inner.is_none() {
return put(index, slot, socket);
}
}
match &mut self.sockets {
ManagedSlice::Borrowed(_) => panic!("adding a socket to a full SocketSet"),
#[cfg(feature = "alloc")]
ManagedSlice::Owned(sockets) => {
sockets.push(SocketStorage { inner: None });
let index = sockets.len() - 1;
put(index, &mut sockets[index], socket)
}
}
}
pub fn get<T: AnySocket<'a>>(&self, handle: SocketHandle) -> &T {
match self.sockets[handle.0].inner.as_ref() {
Some(item) => {
T::downcast(&item.socket).expect("handle refers to a socket of a wrong type")
}
None => panic!("handle does not refer to a valid socket"),
}
}
pub fn get_mut<T: AnySocket<'a>>(&mut self, handle: SocketHandle) -> &mut T {
match self.sockets[handle.0].inner.as_mut() {
Some(item) => T::downcast_mut(&mut item.socket)
.expect("handle refers to a socket of a wrong type"),
None => panic!("handle does not refer to a valid socket"),
}
}
pub fn remove(&mut self, handle: SocketHandle) -> Socket<'a> {
net_trace!("[{}]: removing", handle.0);
match self.sockets[handle.0].inner.take() {
Some(item) => item.socket,
None => panic!("handle does not refer to a valid socket"),
}
}
pub fn iter(&self) -> impl Iterator<Item = (SocketHandle, &Socket<'a>)> {
self.items().map(|i| (i.meta.handle, &i.socket))
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (SocketHandle, &mut Socket<'a>)> {
self.items_mut().map(|i| (i.meta.handle, &mut i.socket))
}
pub(crate) fn items(&self) -> impl Iterator<Item = &Item<'a>> + '_ {
self.sockets.iter().filter_map(|x| x.inner.as_ref())
}
pub(crate) fn items_mut(&mut self) -> impl Iterator<Item = &mut Item<'a>> + '_ {
self.sockets.iter_mut().filter_map(|x| x.inner.as_mut())
}
}