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#[cfg(feature = "async")]
82pub trait AsyncLink {
84 fn open(
86 &mut self,
87 geometry: &Geometry,
88 ) -> impl std::future::Future<Output = Result<(), LinkError>>;
89
90 fn close(&mut self) -> impl std::future::Future<Output = Result<(), LinkError>>;
92
93 #[doc(hidden)]
94 fn update(&mut self, _: &Geometry) -> impl std::future::Future<Output = Result<(), LinkError>>;
95
96 fn alloc_tx_buffer(
98 &mut self,
99 ) -> impl std::future::Future<Output = Result<Vec<TxMessage>, LinkError>>;
100
101 fn send(
103 &mut self,
104 tx: Vec<TxMessage>,
105 ) -> impl std::future::Future<Output = Result<(), LinkError>>;
106
107 fn receive(
109 &mut self,
110 rx: &mut [RxMessage],
111 ) -> impl std::future::Future<Output = Result<(), LinkError>>;
112
113 #[must_use]
115 fn is_open(&self) -> bool;
116
117 fn ensure_is_open(&self) -> Result<(), LinkError>;
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 struct MockLink {
126 is_open: bool,
127 open_called: bool,
128 close_called: bool,
129 update_called: bool,
130 alloc_called: bool,
131 send_called: bool,
132 receive_called: bool,
133 }
134
135 impl MockLink {
136 fn new() -> Self {
137 Self {
138 is_open: false,
139 open_called: false,
140 close_called: false,
141 update_called: false,
142 alloc_called: false,
143 send_called: false,
144 receive_called: false,
145 }
146 }
147 }
148
149 impl Link for MockLink {
150 fn open(&mut self, _geometry: &Geometry) -> Result<(), LinkError> {
151 self.open_called = true;
152 self.is_open = true;
153 Ok(())
154 }
155
156 fn close(&mut self) -> Result<(), LinkError> {
157 self.close_called = true;
158 self.is_open = false;
159 Ok(())
160 }
161
162 fn update(&mut self, _geometry: &Geometry) -> Result<(), LinkError> {
163 self.update_called = true;
164 Ok(())
165 }
166
167 fn alloc_tx_buffer(&mut self) -> Result<Vec<TxMessage>, LinkError> {
168 self.alloc_called = true;
169 Ok(vec![])
170 }
171
172 fn send(&mut self, _tx: Vec<TxMessage>) -> Result<(), LinkError> {
173 self.send_called = true;
174 Ok(())
175 }
176
177 fn receive(&mut self, _rx: &mut [RxMessage]) -> Result<(), LinkError> {
178 self.receive_called = true;
179 Ok(())
180 }
181
182 fn is_open(&self) -> bool {
183 self.is_open
184 }
185 }
186
187 #[test]
188 fn open() -> Result<(), LinkError> {
189 let mut link = MockLink::new();
190 let geometry = Geometry::new(vec![]);
191
192 assert!(!Link::is_open(&link));
193 Link::open(&mut link, &geometry)?;
194 assert!(link.open_called);
195 assert!(Link::is_open(&link));
196
197 Ok(())
198 }
199
200 #[test]
201 fn close() -> Result<(), LinkError> {
202 let mut link = MockLink::new();
203 link.is_open = true;
204
205 Link::close(&mut link)?;
206 assert!(link.close_called);
207 assert!(!Link::is_open(&link));
208
209 Ok(())
210 }
211
212 #[test]
213 fn update() -> Result<(), LinkError> {
214 let mut link = MockLink::new();
215 let geometry = Geometry::new(vec![]);
216
217 Link::update(&mut link, &geometry)?;
218 assert!(link.update_called);
219
220 Ok(())
221 }
222
223 #[test]
224 fn alloc_tx_buffer() -> Result<(), LinkError> {
225 let mut link = MockLink::new();
226
227 Link::alloc_tx_buffer(&mut link)?;
228 assert!(link.alloc_called);
229
230 Ok(())
231 }
232
233 #[test]
234 fn send() -> Result<(), LinkError> {
235 let mut link = MockLink::new();
236 let tx = vec![];
237
238 Link::send(&mut link, tx)?;
239 assert!(link.send_called);
240
241 Ok(())
242 }
243
244 #[test]
245 fn receive() -> Result<(), LinkError> {
246 let mut link = MockLink::new();
247 let mut rx = vec![];
248
249 Link::receive(&mut link, &mut rx)?;
250 assert!(link.receive_called);
251
252 Ok(())
253 }
254
255 #[test]
256 fn is_open() {
257 let mut link = MockLink::new();
258
259 assert!(!Link::is_open(&link));
260 link.is_open = true;
261 assert!(Link::is_open(&link));
262 }
263
264 #[test]
265 fn ensure_is_open() {
266 let mut link = MockLink::new();
267
268 let result = Link::ensure_is_open(&link);
269 assert_eq!(Err(LinkError::closed()), result);
270 link.is_open = true;
271 assert!(Link::ensure_is_open(&link).is_ok());
272 }
273}