1 use core::fmt; 2 use managed::ManagedSlice; 3 4 use super::socket_meta::Meta; 5 use crate::socket::{AnySocket, Socket}; 6 7 /// Opaque struct with space for storing one socket. 8 /// 9 /// This is public so you can use it to allocate space for storing 10 /// sockets when creating an Interface. 11 #[derive(Debug, Default)] 12 pub struct SocketStorage<'a> { 13 inner: Option<Item<'a>>, 14 } 15 16 impl<'a> SocketStorage<'a> { 17 pub const EMPTY: Self = Self { inner: None }; 18 } 19 20 /// An item of a socket set. 21 #[derive(Debug)] 22 pub(crate) struct Item<'a> { 23 pub(crate) meta: Meta, 24 pub(crate) socket: Socket<'a>, 25 } 26 27 /// A handle, identifying a socket in an Interface. 28 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)] 29 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 30 pub struct SocketHandle(usize); 31 32 impl fmt::Display for SocketHandle { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result33 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 34 write!(f, "#{}", self.0) 35 } 36 } 37 38 /// An extensible set of sockets. 39 /// 40 /// The lifetime `'a` is used when storing a `Socket<'a>`. 41 #[derive(Debug)] 42 pub struct SocketSet<'a> { 43 sockets: ManagedSlice<'a, SocketStorage<'a>>, 44 } 45 46 impl<'a> SocketSet<'a> { 47 /// Create a socket set using the provided storage. new<SocketsT>(sockets: SocketsT) -> SocketSet<'a> where SocketsT: Into<ManagedSlice<'a, SocketStorage<'a>>>,48 pub fn new<SocketsT>(sockets: SocketsT) -> SocketSet<'a> 49 where 50 SocketsT: Into<ManagedSlice<'a, SocketStorage<'a>>>, 51 { 52 let sockets = sockets.into(); 53 SocketSet { sockets } 54 } 55 56 /// Add a socket to the set, and return its handle. 57 /// 58 /// # Panics 59 /// This function panics if the storage is fixed-size (not a `Vec`) and is full. add<T: AnySocket<'a>>(&mut self, socket: T) -> SocketHandle60 pub fn add<T: AnySocket<'a>>(&mut self, socket: T) -> SocketHandle { 61 fn put<'a>(index: usize, slot: &mut SocketStorage<'a>, socket: Socket<'a>) -> SocketHandle { 62 net_trace!("[{}]: adding", index); 63 let handle = SocketHandle(index); 64 let mut meta = Meta::default(); 65 meta.handle = handle; 66 *slot = SocketStorage { 67 inner: Some(Item { meta, socket }), 68 }; 69 handle 70 } 71 72 let socket = socket.upcast(); 73 74 for (index, slot) in self.sockets.iter_mut().enumerate() { 75 if slot.inner.is_none() { 76 return put(index, slot, socket); 77 } 78 } 79 80 match &mut self.sockets { 81 ManagedSlice::Borrowed(_) => panic!("adding a socket to a full SocketSet"), 82 #[cfg(feature = "alloc")] 83 ManagedSlice::Owned(sockets) => { 84 sockets.push(SocketStorage { inner: None }); 85 let index = sockets.len() - 1; 86 put(index, &mut sockets[index], socket) 87 } 88 } 89 } 90 91 /// Get a socket from the set by its handle, as mutable. 92 /// 93 /// # Panics 94 /// This function may panic if the handle does not belong to this socket set 95 /// or the socket has the wrong type. get<T: AnySocket<'a>>(&self, handle: SocketHandle) -> &T96 pub fn get<T: AnySocket<'a>>(&self, handle: SocketHandle) -> &T { 97 match self.sockets[handle.0].inner.as_ref() { 98 Some(item) => { 99 T::downcast(&item.socket).expect("handle refers to a socket of a wrong type") 100 } 101 None => panic!("handle does not refer to a valid socket"), 102 } 103 } 104 105 /// Get a mutable socket from the set by its handle, as mutable. 106 /// 107 /// # Panics 108 /// This function may panic if the handle does not belong to this socket set 109 /// or the socket has the wrong type. get_mut<T: AnySocket<'a>>(&mut self, handle: SocketHandle) -> &mut T110 pub fn get_mut<T: AnySocket<'a>>(&mut self, handle: SocketHandle) -> &mut T { 111 match self.sockets[handle.0].inner.as_mut() { 112 Some(item) => T::downcast_mut(&mut item.socket) 113 .expect("handle refers to a socket of a wrong type"), 114 None => panic!("handle does not refer to a valid socket"), 115 } 116 } 117 118 /// Remove a socket from the set, without changing its state. 119 /// 120 /// # Panics 121 /// This function may panic if the handle does not belong to this socket set. remove(&mut self, handle: SocketHandle) -> Socket<'a>122 pub fn remove(&mut self, handle: SocketHandle) -> Socket<'a> { 123 net_trace!("[{}]: removing", handle.0); 124 match self.sockets[handle.0].inner.take() { 125 Some(item) => item.socket, 126 None => panic!("handle does not refer to a valid socket"), 127 } 128 } 129 130 /// Get an iterator to the inner sockets. iter(&self) -> impl Iterator<Item = (SocketHandle, &Socket<'a>)>131 pub fn iter(&self) -> impl Iterator<Item = (SocketHandle, &Socket<'a>)> { 132 self.items().map(|i| (i.meta.handle, &i.socket)) 133 } 134 135 /// Get a mutable iterator to the inner sockets. iter_mut(&mut self) -> impl Iterator<Item = (SocketHandle, &mut Socket<'a>)>136 pub fn iter_mut(&mut self) -> impl Iterator<Item = (SocketHandle, &mut Socket<'a>)> { 137 self.items_mut().map(|i| (i.meta.handle, &mut i.socket)) 138 } 139 140 /// Iterate every socket in this set. items(&self) -> impl Iterator<Item = &Item<'a>> + '_141 pub(crate) fn items(&self) -> impl Iterator<Item = &Item<'a>> + '_ { 142 self.sockets.iter().filter_map(|x| x.inner.as_ref()) 143 } 144 145 /// Iterate every socket in this set. items_mut(&mut self) -> impl Iterator<Item = &mut Item<'a>> + '_146 pub(crate) fn items_mut(&mut self) -> impl Iterator<Item = &mut Item<'a>> + '_ { 147 self.sockets.iter_mut().filter_map(|x| x.inner.as_mut()) 148 } 149 } 150