zmk_studio_api/transport/
serial.rs1use std::io::{Read, Write};
2use std::time::Duration;
3
4const DEFAULT_BAUD_RATE: u32 = 12_500;
5const DEFAULT_TIMEOUT: Duration = Duration::from_millis(500);
6
7#[derive(Debug)]
8pub enum SerialTransportError {
9 Open(serialport::Error),
10 NoMatchingPort,
11}
12
13impl std::fmt::Display for SerialTransportError {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 match self {
16 Self::Open(err) => write!(f, "Failed to open serial port: {err}"),
17 Self::NoMatchingPort => write!(f, "No matching serial port found"),
18 }
19 }
20}
21
22impl std::error::Error for SerialTransportError {
23 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
24 match self {
25 Self::Open(err) => Some(err),
26 Self::NoMatchingPort => None,
27 }
28 }
29}
30
31impl From<serialport::Error> for SerialTransportError {
32 fn from(value: serialport::Error) -> Self {
33 Self::Open(value)
34 }
35}
36
37pub struct SerialTransport {
38 inner: Box<dyn serialport::SerialPort>,
39}
40
41impl SerialTransport {
42 pub fn open(path: &str) -> Result<Self, SerialTransportError> {
43 Self::open_with(path, DEFAULT_BAUD_RATE, DEFAULT_TIMEOUT)
44 }
45
46 fn open_with(
47 path: &str,
48 baud_rate: u32,
49 timeout: Duration,
50 ) -> Result<Self, SerialTransportError> {
51 let port = serialport::new(path, baud_rate).timeout(timeout).open()?;
52 Ok(Self { inner: port })
53 }
54}
55
56impl Read for SerialTransport {
57 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
58 self.inner.read(buf)
59 }
60}
61
62impl Write for SerialTransport {
63 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
64 self.inner.write(buf)
65 }
66
67 fn flush(&mut self) -> std::io::Result<()> {
68 self.inner.flush()
69 }
70}