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