kenwood_thd75/transport/
either.rs

1//! Enum transport that dispatches to either Serial, Bluetooth, or Mock.
2
3use crate::error::TransportError;
4use crate::transport::Transport;
5use crate::transport::mock::MockTransport;
6use crate::transport::serial::SerialTransport;
7
8#[cfg(target_os = "macos")]
9use crate::transport::bluetooth::BluetoothTransport;
10
11/// A transport that can be USB serial, Bluetooth RFCOMM, or a
12/// programmed mock transport used by integration tests.
13#[derive(Debug)]
14pub enum EitherTransport {
15    /// USB CDC ACM serial.
16    Serial(SerialTransport),
17    /// Native macOS `IOBluetooth` RFCOMM.
18    #[cfg(target_os = "macos")]
19    Bluetooth(BluetoothTransport),
20    /// Programmed mock transport (integration tests, CLI `--mock-radio`).
21    Mock(MockTransport),
22}
23
24impl Transport for EitherTransport {
25    fn set_baud_rate(&mut self, baud: u32) -> Result<(), TransportError> {
26        match self {
27            Self::Serial(s) => s.set_baud_rate(baud),
28            #[cfg(target_os = "macos")]
29            Self::Bluetooth(_) => Ok(()), // BT has fixed baud
30            Self::Mock(m) => m.set_baud_rate(baud),
31        }
32    }
33
34    async fn write(&mut self, data: &[u8]) -> Result<(), TransportError> {
35        match self {
36            Self::Serial(s) => s.write(data).await,
37            #[cfg(target_os = "macos")]
38            Self::Bluetooth(b) => b.write(data).await,
39            Self::Mock(m) => m.write(data).await,
40        }
41    }
42
43    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, TransportError> {
44        match self {
45            Self::Serial(s) => s.read(buf).await,
46            #[cfg(target_os = "macos")]
47            Self::Bluetooth(b) => b.read(buf).await,
48            Self::Mock(m) => m.read(buf).await,
49        }
50    }
51
52    async fn close(&mut self) -> Result<(), TransportError> {
53        match self {
54            Self::Serial(s) => s.close().await,
55            #[cfg(target_os = "macos")]
56            Self::Bluetooth(b) => b.close().await,
57            Self::Mock(m) => m.close().await,
58        }
59    }
60}