//! POSIX serial transport via `tokio-serial`. use async_trait::async_trait; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio_serial::SerialPortBuilderExt; use shared::error::{AutopilotError, Result}; use super::Transport; #[derive(Debug)] pub struct SerialTransport { port: tokio_serial::SerialStream, } impl SerialTransport { pub fn open(path: &str, baud: u32) -> Result { let port = tokio_serial::new(path, baud) .timeout(std::time::Duration::from_millis(500)) .data_bits(tokio_serial::DataBits::Eight) .parity(tokio_serial::Parity::None) .stop_bits(tokio_serial::StopBits::One) .flow_control(tokio_serial::FlowControl::None) .open_native_async() .map_err(|e| AutopilotError::Network(format!("serial open {path}: {e}")))?; Ok(Self { port }) } } #[async_trait] impl Transport for SerialTransport { async fn read(&mut self, buf: &mut [u8]) -> Result { self.port .read(buf) .await .map_err(|e| AutopilotError::Network(format!("serial read: {e}"))) } async fn write_all(&mut self, buf: &[u8]) -> Result<()> { self.port .write_all(buf) .await .map_err(|e| AutopilotError::Network(format!("serial write: {e}")))?; Ok(()) } }