tauri-plugin-serialplugin 2.22.0

Access the current process of your Tauri application.
use std::io::{self, Read, Write};
use serialport::{self, SerialPort};
use std::time::Duration;
use crate::state::{ConnectedPort, PortState, SerialportInfo};

#[allow(dead_code)]
pub trait SerialPortTrait: Read + Write + Send {
    fn name(&self) -> Option<String>;
    fn baud_rate(&self) -> io::Result<u32>;
    fn data_bits(&self) -> io::Result<serialport::DataBits>;
    fn flow_control(&self) -> io::Result<serialport::FlowControl>;
    fn parity(&self) -> io::Result<serialport::Parity>;
    fn stop_bits(&self) -> io::Result<serialport::StopBits>;
    fn timeout(&self) -> io::Result<std::time::Duration>;
    fn set_baud_rate(&mut self, baud_rate: u32) -> io::Result<()>;
    fn set_data_bits(&mut self, data_bits: serialport::DataBits) -> io::Result<()>;
    fn set_flow_control(&mut self, flow_control: serialport::FlowControl) -> io::Result<()>;
    fn set_parity(&mut self, parity: serialport::Parity) -> io::Result<()>;
    fn set_stop_bits(&mut self, stop_bits: serialport::StopBits) -> io::Result<()>;
    fn set_timeout(&mut self, timeout: std::time::Duration) -> io::Result<()>;
    fn write_request_to_send(&mut self, level: bool) -> io::Result<()>;
    fn write_data_terminal_ready(&mut self, level: bool) -> io::Result<()>;
    fn read_clear_to_send(&mut self) -> io::Result<bool>;
    fn read_data_set_ready(&mut self) -> io::Result<bool>;
    fn read_ring_indicator(&mut self) -> io::Result<bool>;
    fn read_carrier_detect(&mut self) -> io::Result<bool>;
    fn bytes_to_read(&self) -> io::Result<u32>;
    fn bytes_to_write(&self) -> io::Result<u32>;
    fn clear(&self, buffer_to_clear: serialport::ClearBuffer) -> io::Result<()>;
    fn try_clone(&self) -> io::Result<Box<dyn SerialPort>>;
    fn set_break(&self) -> io::Result<()>;
    fn clear_break(&self) -> io::Result<()>;
}

#[allow(dead_code)]
pub struct MockSerialPort {
    pub buffer: Vec<u8>,
    pub baud_rate: u32,
    pub data_bits: serialport::DataBits,
    pub flow_control: serialport::FlowControl,
    pub parity: serialport::Parity,
    pub stop_bits: serialport::StopBits,
    pub timeout: Duration,
}

#[allow(dead_code)]
impl MockSerialPort {
    pub fn new() -> Self {
        Self {
            buffer: Vec::new(),
            baud_rate: 9600,
            data_bits: serialport::DataBits::Eight,
            flow_control: serialport::FlowControl::None,
            parity: serialport::Parity::None,
            stop_bits: serialport::StopBits::One,
            timeout: Duration::from_millis(1000),
        }
    }
}

impl SerialPort for MockSerialPort {
    fn name(&self) -> Option<String> {
        Some("COM1".to_string())
    }

    fn baud_rate(&self) -> Result<u32, serialport::Error> {
        Ok(self.baud_rate)
    }

    fn data_bits(&self) -> Result<serialport::DataBits, serialport::Error> {
        Ok(self.data_bits)
    }

    fn flow_control(&self) -> Result<serialport::FlowControl, serialport::Error> {
        Ok(self.flow_control)
    }

    fn parity(&self) -> Result<serialport::Parity, serialport::Error> {
        Ok(self.parity)
    }

    fn stop_bits(&self) -> Result<serialport::StopBits, serialport::Error> {
        Ok(self.stop_bits)
    }

    fn timeout(&self) -> Duration {
        self.timeout
    }

    fn set_baud_rate(&mut self, rate: u32) -> Result<(), serialport::Error> {
        self.baud_rate = rate;
        Ok(())
    }

    fn set_data_bits(&mut self, bits: serialport::DataBits) -> Result<(), serialport::Error> {
        self.data_bits = bits;
        Ok(())
    }

    fn set_flow_control(&mut self, flow: serialport::FlowControl) -> Result<(), serialport::Error> {
        self.flow_control = flow;
        Ok(())
    }

    fn set_parity(&mut self, parity: serialport::Parity) -> Result<(), serialport::Error> {
        self.parity = parity;
        Ok(())
    }

    fn set_stop_bits(&mut self, bits: serialport::StopBits) -> Result<(), serialport::Error> {
        self.stop_bits = bits;
        Ok(())
    }

    fn set_timeout(&mut self, timeout: Duration) -> Result<(), serialport::Error> {
        self.timeout = timeout;
        Ok(())
    }

    fn write_request_to_send(&mut self, _level: bool) -> Result<(), serialport::Error> {
        Ok(())
    }

    fn write_data_terminal_ready(&mut self, _level: bool) -> Result<(), serialport::Error> {
        Ok(())
    }

    fn read_clear_to_send(&mut self) -> Result<bool, serialport::Error> {
        Ok(true)
    }

    fn read_data_set_ready(&mut self) -> Result<bool, serialport::Error> {
        Ok(true)
    }

    fn read_ring_indicator(&mut self) -> Result<bool, serialport::Error> {
        Ok(true)
    }

    fn read_carrier_detect(&mut self) -> Result<bool, serialport::Error> {
        Ok(true)
    }

    fn bytes_to_read(&self) -> Result<u32, serialport::Error> {
        Ok(self.buffer.len() as u32)
    }

    fn bytes_to_write(&self) -> Result<u32, serialport::Error> {
        Ok(0)
    }

    fn clear(&self, _buffer_to_clear: serialport::ClearBuffer) -> Result<(), serialport::Error> {
        Ok(())
    }

    fn try_clone(&self) -> Result<Box<dyn SerialPort>, serialport::Error> {
        Ok(Box::new(MockSerialPort {
            buffer: self.buffer.clone(),
            baud_rate: self.baud_rate,
            data_bits: self.data_bits,
            flow_control: self.flow_control,
            parity: self.parity,
            stop_bits: self.stop_bits,
            timeout: self.timeout,
        }))
    }

    fn set_break(&self) -> Result<(), serialport::Error> {
        Ok(())
    }

    fn clear_break(&self) -> Result<(), serialport::Error> {
        Ok(())
    }
}

impl Read for MockSerialPort {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        let len = std::cmp::min(buf.len(), self.buffer.len());
        if len > 0 {
            buf[..len].copy_from_slice(&self.buffer[..len]);
            self.buffer.drain(..len);
        }
        Ok(len)
    }
}

impl Write for MockSerialPort {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        self.buffer.extend_from_slice(buf);
        Ok(buf.len())
    }

    fn flush(&mut self) -> std::io::Result<()> {
        Ok(())
    }
}

#[allow(dead_code)]
pub fn create_mock_serialport_info() -> SerialportInfo {
    SerialportInfo {
        state: PortState::Connected(ConnectedPort {
            port: Box::new(MockSerialPort::new()),
            sender: None,
            thread_handle: None,
        }),
    }
}