use crate::error::Result;
#[cfg(feature = "tp-cbus")]
pub mod cbus;
#[cfg(feature = "tp-poll")]
pub mod poll;
#[cfg(feature = "picodata")]
pub type PicodataTransport<'a> = cbus::CBusTransport<'a>;
#[cfg(feature = "vanilla")]
pub type VanillaTransport = poll::PollTransport;
pub trait Transport {
type Sender<T>: TransportSender<T> + Send
where
T: Send;
type Receiver<T>: TransportReceiver<T>
where
T: Send;
fn create_channel<T: Send>(&self) -> (Self::Sender<T>, Self::Receiver<T>);
}
#[cfg_attr(feature = "test", enum_dispatch::enum_dispatch)]
pub trait TransportSender<T> {
fn send(self, data: T) -> Result<()>;
}
#[cfg_attr(feature = "test", enum_dispatch::enum_dispatch)]
pub trait TransportReceiver<T> {
fn receive(self) -> Result<T>;
}
#[cfg(feature = "test")]
pub mod test {
use std::iter::{empty, once_with};
use super::{cbus::CBusTransport, poll::PollTransport, *};
use enum_dispatch::enum_dispatch;
#[derive(Debug)]
pub enum GeneralTransport<'a> {
CBus(CBusTransport<'a>),
Poll(PollTransport),
}
impl<'a> GeneralTransport<'a> {
pub fn all_iter() -> impl Iterator<Item = GeneralTransport<'static>> {
empty()
.chain(once_with(|| GeneralTransport::CBus(Default::default())))
.chain(once_with(|| {
GeneralTransport::Poll(PollTransport::default())
}))
}
}
impl<'a> Transport for GeneralTransport<'a> {
type Sender<T> = GeneralTransportSender<'a, T>
where
T: Send;
type Receiver<T> = GeneralTransportReceiver<'a, T>
where
T: Send;
fn create_channel<T: Send>(&self) -> (Self::Sender<T>, Self::Receiver<T>) {
match self {
GeneralTransport::CBus(tp) => cast_channel(tp.create_channel()),
GeneralTransport::Poll(tp) => cast_channel(tp.create_channel()),
}
}
}
#[enum_dispatch(TransportSender<T>)]
pub enum GeneralTransportSender<'a, T: Send> {
CBus(<CBusTransport<'a> as Transport>::Sender<T>),
Poll(<PollTransport as Transport>::Sender<T>),
}
#[enum_dispatch(TransportReceiver<T>)]
pub enum GeneralTransportReceiver<'a, T: Send> {
CBus(<CBusTransport<'a> as Transport>::Receiver<T>),
Poll(<PollTransport as Transport>::Receiver<T>),
}
fn cast_channel<TX, RX, ToTX: From<TX>, ToRX: From<RX>>((tx, rx): (TX, RX)) -> (ToTX, ToRX) {
(tx.into(), rx.into())
}
}