ergot_base/socket/
owned.rs

1//! "Owned" sockets
2//!
3//! "Owned" sockets require `T: 'static`, and store messages in their deserialized `T` form,
4//! rather as serialized bytes.
5//!
6//! This module contains versions of the [`raw_owned`](crate::socket::raw_owned) socket types
7//! that use a specific kind of storage.
8//!
9//! Currently we support:
10//!
11//! * `single` sockets, which use an `Option<T>` for storage, suitable for one-shot responses
12//! * `stack_vec` sockets, which use a heapless `Deque` for storage, and have a const-generic
13//!   size bound
14//! * `std_bounded` socket, which use a `std` `VecDeque` with an upper limit on the capacity
15
16macro_rules! wrapper {
17    ($sto: ty, $($arr: ident)?) => {
18        #[repr(transparent)]
19        pub struct Socket<T, R, M, $(const $arr: usize)?>
20        where
21            T: Clone + serde::de::DeserializeOwned + 'static,
22            R: mutex::ScopedRawMutex + 'static,
23            M: $crate::interface_manager::InterfaceManager + 'static,
24        {
25            socket: $crate::socket::raw_owned::Socket<$sto, T, R, M>,
26        }
27
28        pub struct SocketHdl<'a, T, R, M, $(const $arr: usize)?>
29        where
30            T: Clone + serde::de::DeserializeOwned + 'static,
31            R: mutex::ScopedRawMutex + 'static,
32            M: $crate::interface_manager::InterfaceManager + 'static,
33        {
34            hdl: $crate::socket::raw_owned::SocketHdl<'a, $sto, T, R, M>,
35        }
36
37        pub struct Recv<'a, 'b, T, R, M, $(const $arr: usize)?>
38        where
39            T: Clone + serde::de::DeserializeOwned + 'static,
40            R: mutex::ScopedRawMutex + 'static,
41            M: $crate::interface_manager::InterfaceManager + 'static,
42        {
43            recv: $crate::socket::raw_owned::Recv<'a, 'b, $sto, T, R, M>,
44        }
45
46        impl<T, R, M, $(const $arr: usize)?> Socket<T, R, M, $($arr)?>
47        where
48            T: Clone + serde::de::DeserializeOwned + 'static,
49            R: mutex::ScopedRawMutex + 'static,
50            M: $crate::interface_manager::InterfaceManager + 'static,
51        {
52            pub fn attach<'a>(self: core::pin::Pin<&'a mut Self>) -> SocketHdl<'a, T, R, M, $($arr)?> {
53                let socket: core::pin::Pin<&'a mut $crate::socket::raw_owned::Socket<$sto, T, R, M>>
54                    = unsafe { self.map_unchecked_mut(|me| &mut me.socket) };
55                SocketHdl {
56                    hdl: socket.attach(),
57                }
58            }
59
60            pub fn attach_broadcast<'a>(
61                self: core::pin::Pin<&'a mut Self>,
62            ) -> SocketHdl<'a, T, R, M, $($arr)?> {
63                let socket: core::pin::Pin<&'a mut $crate::socket::raw_owned::Socket<$sto, T, R, M>>
64                    = unsafe { self.map_unchecked_mut(|me| &mut me.socket) };
65                SocketHdl {
66                    hdl: socket.attach_broadcast(),
67                }
68            }
69
70            pub fn stack(&self) -> &'static crate::net_stack::NetStack<R, M> {
71                self.socket.stack()
72            }
73        }
74
75        impl<'a, T, R, M, $(const $arr: usize)?> SocketHdl<'a, T, R, M, $($arr)?>
76        where
77            T: Clone + serde::de::DeserializeOwned + 'static,
78            R: mutex::ScopedRawMutex + 'static,
79            M: $crate::interface_manager::InterfaceManager + 'static,
80        {
81            pub fn port(&self) -> u8 {
82                self.hdl.port()
83            }
84
85            pub fn stack(&self) -> &'static crate::net_stack::NetStack<R, M> {
86                self.hdl.stack()
87            }
88
89            pub fn recv<'b>(&'b mut self) -> Recv<'b, 'a, T, R, M, $($arr)?> {
90                Recv {
91                    recv: self.hdl.recv(),
92                }
93            }
94        }
95
96        impl<T, R, M, $(const $arr: usize)?> Future for Recv<'_, '_, T, R, M, $($arr)?>
97        where
98            T: Clone + serde::de::DeserializeOwned + 'static,
99            R: mutex::ScopedRawMutex + 'static,
100            M: $crate::interface_manager::InterfaceManager + 'static,
101        {
102            type Output = $crate::socket::Response<T>;
103
104            fn poll(
105                self: core::pin::Pin<&mut Self>,
106                cx: &mut core::task::Context<'_>,
107            ) -> core::task::Poll<Self::Output> {
108                let recv: core::pin::Pin<&mut $crate::socket::raw_owned::Recv<'_, '_, $sto, T, R, M>>
109                    = unsafe { self.map_unchecked_mut(|me| &mut me.recv) };
110                recv.poll(cx)
111            }
112        }
113    };
114}
115
116pub mod single {
117    use mutex::ScopedRawMutex;
118    use serde::de::DeserializeOwned;
119
120    use crate::{
121        Key,
122        interface_manager::InterfaceManager,
123        net_stack::NetStack,
124        socket::{Attributes, raw_owned},
125    };
126
127    impl<T: 'static> raw_owned::Storage<T> for Option<T> {
128        #[inline]
129        fn is_full(&self) -> bool {
130            self.is_some()
131        }
132
133        #[inline]
134        fn is_empty(&self) -> bool {
135            self.is_none()
136        }
137
138        #[inline]
139        fn push(&mut self, t: T) -> Result<(), raw_owned::StorageFull> {
140            if self.is_some() {
141                return Err(raw_owned::StorageFull);
142            }
143            *self = Some(t);
144            Ok(())
145        }
146
147        #[inline]
148        fn try_pop(&mut self) -> Option<T> {
149            self.take()
150        }
151    }
152
153    wrapper!(Option<crate::socket::Response<T>>,);
154
155    impl<T, R, M> Socket<T, R, M>
156    where
157        T: Clone + DeserializeOwned + 'static,
158        R: ScopedRawMutex + 'static,
159        M: InterfaceManager + 'static,
160    {
161        #[inline]
162        pub const fn new(
163            net: &'static NetStack<R, M>,
164            key: Key,
165            attrs: Attributes,
166            name: Option<&str>,
167        ) -> Self {
168            Self {
169                socket: raw_owned::Socket::new(net, key, attrs, None, name),
170            }
171        }
172    }
173}
174
175#[cfg(feature = "std")]
176pub mod std_bounded {
177    use mutex::ScopedRawMutex;
178    use serde::de::DeserializeOwned;
179    use std::collections::VecDeque;
180
181    use crate::{Key, NetStack, interface_manager::InterfaceManager};
182
183    use crate::socket::{Attributes, raw_owned};
184
185    pub struct Bounded<T> {
186        storage: std::collections::VecDeque<T>,
187        max_len: usize,
188    }
189
190    impl<T> Bounded<T> {
191        pub fn with_bound(bound: usize) -> Self {
192            Self {
193                storage: VecDeque::new(),
194                max_len: bound,
195            }
196        }
197    }
198
199    impl<T: 'static> raw_owned::Storage<T> for Bounded<T> {
200        #[inline]
201        fn is_full(&self) -> bool {
202            self.storage.len() >= self.max_len
203        }
204
205        #[inline]
206        fn is_empty(&self) -> bool {
207            self.storage.is_empty()
208        }
209
210        #[inline]
211        fn push(&mut self, t: T) -> Result<(), raw_owned::StorageFull> {
212            if self.is_full() {
213                return Err(raw_owned::StorageFull);
214            }
215            self.storage.push_back(t);
216            Ok(())
217        }
218
219        #[inline]
220        fn try_pop(&mut self) -> Option<T> {
221            self.storage.pop_front()
222        }
223    }
224
225    wrapper!(Bounded<crate::socket::Response<T>>,);
226
227    impl<T, R, M> Socket<T, R, M>
228    where
229        T: Clone + DeserializeOwned + 'static,
230        R: ScopedRawMutex + 'static,
231        M: InterfaceManager + 'static,
232    {
233        #[inline]
234        pub fn new(
235            net: &'static NetStack<R, M>,
236            key: Key,
237            attrs: Attributes,
238            bound: usize,
239            name: Option<&str>,
240        ) -> Self {
241            Self {
242                socket: raw_owned::Socket::new(net, key, attrs, Bounded::with_bound(bound), name),
243            }
244        }
245    }
246}
247
248pub mod stack_vec {
249    use mutex::ScopedRawMutex;
250    use serde::de::DeserializeOwned;
251
252    use crate::{Key, NetStack, interface_manager::InterfaceManager};
253
254    use crate::socket::{Attributes, raw_owned};
255
256    pub struct Bounded<T: 'static, const N: usize> {
257        storage: heapless::Deque<T, N>,
258    }
259
260    impl<T: 'static, const N: usize> Bounded<T, N> {
261        pub const fn new() -> Self {
262            Self {
263                storage: heapless::Deque::new(),
264            }
265        }
266    }
267
268    impl<T: 'static, const N: usize> Default for Bounded<T, N> {
269        fn default() -> Self {
270            Self::new()
271        }
272    }
273
274    impl<T: 'static, const N: usize> raw_owned::Storage<T> for Bounded<T, N> {
275        #[inline]
276        fn is_full(&self) -> bool {
277            self.storage.is_full()
278        }
279
280        #[inline]
281        fn is_empty(&self) -> bool {
282            self.storage.is_empty()
283        }
284
285        #[inline]
286        fn push(&mut self, t: T) -> Result<(), raw_owned::StorageFull> {
287            self.storage
288                .push_back(t)
289                .map_err(|_| raw_owned::StorageFull)
290        }
291
292        #[inline]
293        fn try_pop(&mut self) -> Option<T> {
294            self.storage.pop_front()
295        }
296    }
297
298    wrapper!(Bounded<crate::socket::Response<T>, N>, N);
299
300    impl<T, R, M, const N: usize> Socket<T, R, M, N>
301    where
302        T: Clone + DeserializeOwned + 'static,
303        R: ScopedRawMutex + 'static,
304        M: InterfaceManager + 'static,
305    {
306        #[inline]
307        pub const fn new(
308            net: &'static NetStack<R, M>,
309            key: Key,
310            attrs: Attributes,
311            name: Option<&str>,
312        ) -> Self {
313            Self {
314                socket: raw_owned::Socket::new(net, key, attrs, Bounded::new(), name),
315            }
316        }
317    }
318}