mod buffer_pool;
mod datagram;
mod error;
pub use buffer_pool::*;
pub use datagram::*;
pub use error::LinkError;
use crate::geometry::Geometry;
pub trait Link: Send {
fn open(&mut self, geometry: &Geometry) -> Result<(), LinkError>;
fn close(&mut self) -> Result<(), LinkError>;
#[doc(hidden)]
fn update(&mut self, _: &Geometry) -> Result<(), LinkError> {
Ok(())
}
fn alloc_tx_buffer(&mut self) -> Result<Vec<TxMessage>, LinkError>;
fn send(&mut self, tx: Vec<TxMessage>) -> Result<(), LinkError>;
fn receive(&mut self, rx: &mut [RxMessage]) -> Result<(), LinkError>;
#[must_use]
fn is_open(&self) -> bool;
fn ensure_is_open(&self) -> Result<(), LinkError> {
if self.is_open() {
Ok(())
} else {
Err(LinkError::closed())
}
}
}
impl Link for Box<dyn Link> {
fn open(&mut self, geometry: &Geometry) -> Result<(), LinkError> {
self.as_mut().open(geometry)
}
fn close(&mut self) -> Result<(), LinkError> {
self.as_mut().close()
}
fn update(&mut self, geometry: &Geometry) -> Result<(), LinkError> {
self.as_mut().update(geometry)
}
fn alloc_tx_buffer(&mut self) -> Result<Vec<TxMessage>, LinkError> {
self.as_mut().alloc_tx_buffer()
}
fn send(&mut self, tx: Vec<TxMessage>) -> Result<(), LinkError> {
self.as_mut().send(tx)
}
fn receive(&mut self, rx: &mut [RxMessage]) -> Result<(), LinkError> {
self.as_mut().receive(rx)
}
fn is_open(&self) -> bool {
self.as_ref().is_open()
}
fn ensure_is_open(&self) -> Result<(), LinkError> {
self.as_ref().ensure_is_open()
}
}
#[cfg(feature = "async")]
pub trait AsyncLink {
fn open(
&mut self,
geometry: &Geometry,
) -> impl std::future::Future<Output = Result<(), LinkError>>;
fn close(&mut self) -> impl std::future::Future<Output = Result<(), LinkError>>;
#[doc(hidden)]
fn update(&mut self, _: &Geometry) -> impl std::future::Future<Output = Result<(), LinkError>>;
fn alloc_tx_buffer(
&mut self,
) -> impl std::future::Future<Output = Result<Vec<TxMessage>, LinkError>>;
fn send(
&mut self,
tx: Vec<TxMessage>,
) -> impl std::future::Future<Output = Result<(), LinkError>>;
fn receive(
&mut self,
rx: &mut [RxMessage],
) -> impl std::future::Future<Output = Result<(), LinkError>>;
#[must_use]
fn is_open(&self) -> bool;
fn ensure_is_open(&self) -> Result<(), LinkError>;
}
#[cfg(test)]
mod tests {
use super::*;
struct MockLink {
is_open: bool,
open_called: bool,
close_called: bool,
update_called: bool,
alloc_called: bool,
send_called: bool,
receive_called: bool,
}
impl MockLink {
fn new() -> Self {
Self {
is_open: false,
open_called: false,
close_called: false,
update_called: false,
alloc_called: false,
send_called: false,
receive_called: false,
}
}
}
impl Link for MockLink {
fn open(&mut self, _geometry: &Geometry) -> Result<(), LinkError> {
self.open_called = true;
self.is_open = true;
Ok(())
}
fn close(&mut self) -> Result<(), LinkError> {
self.close_called = true;
self.is_open = false;
Ok(())
}
fn update(&mut self, _geometry: &Geometry) -> Result<(), LinkError> {
self.update_called = true;
Ok(())
}
fn alloc_tx_buffer(&mut self) -> Result<Vec<TxMessage>, LinkError> {
self.alloc_called = true;
Ok(vec![])
}
fn send(&mut self, _tx: Vec<TxMessage>) -> Result<(), LinkError> {
self.send_called = true;
Ok(())
}
fn receive(&mut self, _rx: &mut [RxMessage]) -> Result<(), LinkError> {
self.receive_called = true;
Ok(())
}
fn is_open(&self) -> bool {
self.is_open
}
}
#[test]
fn open() -> Result<(), LinkError> {
let mut link = MockLink::new();
let geometry = Geometry::new(vec![]);
assert!(!Link::is_open(&link));
Link::open(&mut link, &geometry)?;
assert!(link.open_called);
assert!(Link::is_open(&link));
Ok(())
}
#[test]
fn close() -> Result<(), LinkError> {
let mut link = MockLink::new();
link.is_open = true;
Link::close(&mut link)?;
assert!(link.close_called);
assert!(!Link::is_open(&link));
Ok(())
}
#[test]
fn update() -> Result<(), LinkError> {
let mut link = MockLink::new();
let geometry = Geometry::new(vec![]);
Link::update(&mut link, &geometry)?;
assert!(link.update_called);
Ok(())
}
#[test]
fn alloc_tx_buffer() -> Result<(), LinkError> {
let mut link = MockLink::new();
Link::alloc_tx_buffer(&mut link)?;
assert!(link.alloc_called);
Ok(())
}
#[test]
fn send() -> Result<(), LinkError> {
let mut link = MockLink::new();
let tx = vec![];
Link::send(&mut link, tx)?;
assert!(link.send_called);
Ok(())
}
#[test]
fn receive() -> Result<(), LinkError> {
let mut link = MockLink::new();
let mut rx = vec![];
Link::receive(&mut link, &mut rx)?;
assert!(link.receive_called);
Ok(())
}
#[test]
fn is_open() {
let mut link = MockLink::new();
assert!(!Link::is_open(&link));
link.is_open = true;
assert!(Link::is_open(&link));
}
#[test]
fn ensure_is_open() {
let mut link = MockLink::new();
let result = Link::ensure_is_open(&link);
assert_eq!(Err(LinkError::closed()), result);
link.is_open = true;
assert!(Link::ensure_is_open(&link).is_ok());
}
}