1mod buffer_pool;
2mod datagram;
3mod error;
4
5pub use buffer_pool::*;
6pub use datagram::*;
7pub use error::LinkError;
8
9use crate::geometry::Geometry;
10
11pub trait Link: Send {
13 fn open(&mut self, geometry: &Geometry) -> Result<(), LinkError>;
15
16 fn close(&mut self) -> Result<(), LinkError>;
18
19 #[doc(hidden)]
20 fn update(&mut self, _: &Geometry) -> Result<(), LinkError> {
21 Ok(())
22 }
23
24 fn alloc_tx_buffer(&mut self) -> Result<Vec<TxMessage>, LinkError>;
26
27 fn send(&mut self, tx: Vec<TxMessage>) -> Result<(), LinkError>;
29
30 fn receive(&mut self, rx: &mut [RxMessage]) -> Result<(), LinkError>;
32
33 #[must_use]
35 fn is_open(&self) -> bool;
36
37 fn ensure_is_open(&self) -> Result<(), LinkError> {
39 if self.is_open() {
40 Ok(())
41 } else {
42 Err(LinkError::closed())
43 }
44 }
45}
46
47impl Link for Box<dyn Link> {
48 fn open(&mut self, geometry: &Geometry) -> Result<(), LinkError> {
49 self.as_mut().open(geometry)
50 }
51
52 fn close(&mut self) -> Result<(), LinkError> {
53 self.as_mut().close()
54 }
55
56 fn update(&mut self, geometry: &Geometry) -> Result<(), LinkError> {
57 self.as_mut().update(geometry)
58 }
59
60 fn alloc_tx_buffer(&mut self) -> Result<Vec<TxMessage>, LinkError> {
61 self.as_mut().alloc_tx_buffer()
62 }
63
64 fn send(&mut self, tx: Vec<TxMessage>) -> Result<(), LinkError> {
65 self.as_mut().send(tx)
66 }
67
68 fn receive(&mut self, rx: &mut [RxMessage]) -> Result<(), LinkError> {
69 self.as_mut().receive(rx)
70 }
71
72 fn is_open(&self) -> bool {
73 self.as_ref().is_open()
74 }
75
76 fn ensure_is_open(&self) -> Result<(), LinkError> {
77 self.as_ref().ensure_is_open()
78 }
79}
80
81#[doc(hidden)]
82pub trait AsyncLink: Link {
83 fn open(
84 &mut self,
85 geometry: &Geometry,
86 ) -> impl std::future::Future<Output = Result<(), LinkError>> {
87 async { <Self as Link>::open(self, geometry) }
88 }
89
90 fn close(&mut self) -> impl std::future::Future<Output = Result<(), LinkError>> {
91 async { <Self as Link>::close(self) }
92 }
93
94 fn update(
95 &mut self,
96 geometry: &Geometry,
97 ) -> impl std::future::Future<Output = Result<(), LinkError>> {
98 async { <Self as Link>::update(self, geometry) }
99 }
100
101 fn alloc_tx_buffer(
102 &mut self,
103 ) -> impl std::future::Future<Output = Result<Vec<TxMessage>, LinkError>> {
104 async { <Self as Link>::alloc_tx_buffer(self) }
105 }
106
107 fn send(
108 &mut self,
109 tx: Vec<TxMessage>,
110 ) -> impl std::future::Future<Output = Result<(), LinkError>> {
111 async { <Self as Link>::send(self, tx) }
112 }
113
114 fn receive(
115 &mut self,
116 rx: &mut [RxMessage],
117 ) -> impl std::future::Future<Output = Result<(), LinkError>> {
118 async { <Self as Link>::receive(self, rx) }
119 }
120
121 #[must_use]
122 fn is_open(&self) -> bool {
123 <Self as Link>::is_open(self)
124 }
125
126 fn ensure_is_open(&self) -> Result<(), LinkError> {
127 <Self as Link>::ensure_is_open(self)
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 struct MockLink {
136 is_open: bool,
137 open_called: bool,
138 close_called: bool,
139 update_called: bool,
140 alloc_called: bool,
141 send_called: bool,
142 receive_called: bool,
143 }
144
145 impl MockLink {
146 fn new() -> Self {
147 Self {
148 is_open: false,
149 open_called: false,
150 close_called: false,
151 update_called: false,
152 alloc_called: false,
153 send_called: false,
154 receive_called: false,
155 }
156 }
157 }
158
159 impl Link for MockLink {
160 fn open(&mut self, _geometry: &Geometry) -> Result<(), LinkError> {
161 self.open_called = true;
162 self.is_open = true;
163 Ok(())
164 }
165
166 fn close(&mut self) -> Result<(), LinkError> {
167 self.close_called = true;
168 self.is_open = false;
169 Ok(())
170 }
171
172 fn update(&mut self, _geometry: &Geometry) -> Result<(), LinkError> {
173 self.update_called = true;
174 Ok(())
175 }
176
177 fn alloc_tx_buffer(&mut self) -> Result<Vec<TxMessage>, LinkError> {
178 self.alloc_called = true;
179 Ok(vec![])
180 }
181
182 fn send(&mut self, _tx: Vec<TxMessage>) -> Result<(), LinkError> {
183 self.send_called = true;
184 Ok(())
185 }
186
187 fn receive(&mut self, _rx: &mut [RxMessage]) -> Result<(), LinkError> {
188 self.receive_called = true;
189 Ok(())
190 }
191
192 fn is_open(&self) -> bool {
193 self.is_open
194 }
195 }
196
197 impl AsyncLink for MockLink {}
198
199 #[test]
200 fn open() -> Result<(), LinkError> {
201 let mut link = MockLink::new();
202 let geometry = Geometry::new(vec![]);
203
204 assert!(!AsyncLink::is_open(&link));
205 futures_lite::future::block_on(AsyncLink::open(&mut link, &geometry))?;
206 assert!(link.open_called);
207 assert!(AsyncLink::is_open(&link));
208
209 Ok(())
210 }
211
212 #[test]
213 fn close() -> Result<(), LinkError> {
214 let mut link = MockLink::new();
215 link.is_open = true;
216
217 futures_lite::future::block_on(AsyncLink::close(&mut link))?;
218 assert!(link.close_called);
219 assert!(!AsyncLink::is_open(&link));
220
221 Ok(())
222 }
223
224 #[test]
225 fn update() -> Result<(), LinkError> {
226 let mut link = MockLink::new();
227 let geometry = Geometry::new(vec![]);
228
229 futures_lite::future::block_on(AsyncLink::update(&mut link, &geometry))?;
230 assert!(link.update_called);
231
232 Ok(())
233 }
234
235 #[test]
236 fn alloc_tx_buffer() -> Result<(), LinkError> {
237 let mut link = MockLink::new();
238
239 futures_lite::future::block_on(AsyncLink::alloc_tx_buffer(&mut link))?;
240 assert!(link.alloc_called);
241
242 Ok(())
243 }
244
245 #[test]
246 fn send() -> Result<(), LinkError> {
247 let mut link = MockLink::new();
248 let tx = vec![];
249
250 futures_lite::future::block_on(AsyncLink::send(&mut link, tx))?;
251 assert!(link.send_called);
252
253 Ok(())
254 }
255
256 #[test]
257 fn receive() -> Result<(), LinkError> {
258 let mut link = MockLink::new();
259 let mut rx = vec![];
260
261 futures_lite::future::block_on(AsyncLink::receive(&mut link, &mut rx))?;
262 assert!(link.receive_called);
263
264 Ok(())
265 }
266
267 #[test]
268 fn is_open() {
269 let mut link = MockLink::new();
270
271 assert!(!AsyncLink::is_open(&link));
272 link.is_open = true;
273 assert!(AsyncLink::is_open(&link));
274 }
275
276 #[test]
277 fn ensure_is_open() {
278 let mut link = MockLink::new();
279
280 let result = AsyncLink::ensure_is_open(&link);
281 assert_eq!(Err(LinkError::closed()), result);
282 link.is_open = true;
283 assert!(AsyncLink::ensure_is_open(&link).is_ok());
284 }
285}