diff --git a/src/interface.rs b/src/interface.rs new file mode 100644 index 0000000..10bbfb9 --- /dev/null +++ b/src/interface.rs @@ -0,0 +1,31 @@ +use std::io; + +pub enum Interface { + SerialPort(Box), + Stdio, +} + +impl io::Write for Interface { + fn write(&mut self, buf: &[u8]) -> io::Result { + match self { + Interface::SerialPort(s) => s.write(buf), + Interface::Stdio => io::stdout().write(buf), + } + } + + fn flush(&mut self) -> io::Result<()> { + match self { + Interface::SerialPort(s) => s.flush(), + Interface::Stdio => io::stdout().flush(), + } + } +} + +impl io::Read for Interface { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + match self { + Interface::SerialPort(s) => s.read(buf), + Interface::Stdio => io::stdin().read(buf), + } + } +} diff --git a/src/main.rs b/src/main.rs index 043a354..413dae5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,7 @@ use crate::serial::{load_serial_settings, serial_thread, Device}; mod data; mod gui; +mod interface; mod io; mod serial; mod toggle; @@ -34,12 +35,8 @@ const PREFS_KEY: &str = "config/gui"; const PREFS_KEY_SERIAL: &str = "config/serial_devices"; fn split(payload: &str) -> Vec { - let mut split_data: Vec<&str> = vec![]; - for s in payload.split(':') { - split_data.extend(s.split(',')); - } - split_data - .iter() + payload + .split(&[':', ',', '=', ' ', '\t']) .map(|x| x.trim()) .flat_map(|x| x.parse::()) .collect() diff --git a/src/serial.rs b/src/serial.rs index 4569d11..85e6f6d 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -1,13 +1,14 @@ -use std::io::{BufRead, BufReader}; +use std::io::{BufRead, BufReader, Write}; use std::sync::mpsc::{Receiver, Sender}; use std::sync::{Arc, RwLock}; use std::time::{Duration, Instant}; use preferences::Preferences; use serde::{Deserialize, Serialize}; -use serialport::{DataBits, FlowControl, Parity, SerialPort, StopBits}; +use serialport::{DataBits, FlowControl, Parity, StopBits}; use crate::data::{get_epoch_ms, SerialDirection}; +use crate::interface::Interface; use crate::{print_to_console, Packet, Print, APP_INFO, PREFS_KEY_SERIAL}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -74,16 +75,13 @@ impl Default for Device { } } -fn serial_write( - port: &mut BufReader>, - cmd: &[u8], -) -> Result { +fn serial_write(port: &mut BufReader, cmd: &[u8]) -> Result { let write_port = port.get_mut(); write_port.write(cmd) } fn serial_read( - port: &mut BufReader>, + port: &mut BufReader, serial_buf: &mut String, ) -> Result { port.read_line(serial_buf) @@ -112,32 +110,41 @@ pub fn serial_thread( let device = get_device(&devices_lock, &device_lock); - let mut port = match serialport::new(&device.name, device.baud_rate) - .timeout(Duration::from_millis(100)) - .open() - { - Ok(p) => { - if let Ok(mut connected) = connected_lock.write() { - *connected = true; - } - print_to_console( - &print_lock, - Print::Ok(format!( - "Connected to serial port: {} @ baud = {}", - device.name, device.baud_rate - )), - ); - BufReader::new(p) + let mut port = if device.name == "stdio" { + if let Ok(mut connected) = connected_lock.write() { + *connected = true; } - Err(err) => { - if let Ok(mut write_guard) = device_lock.write() { - write_guard.name.clear(); + print_to_console(&print_lock, Print::Ok(format!("Connected to stdio"))); + + BufReader::new(Interface::Stdio) + } else { + match serialport::new(&device.name, device.baud_rate) + .timeout(Duration::from_millis(100)) + .open() + { + Ok(p) => { + if let Ok(mut connected) = connected_lock.write() { + *connected = true; + } + print_to_console( + &print_lock, + Print::Ok(format!( + "Connected to serial port: {} @ baud = {}", + device.name, device.baud_rate + )), + ); + BufReader::new(Interface::SerialPort(p)) + } + Err(err) => { + if let Ok(mut write_guard) = device_lock.write() { + write_guard.name.clear(); + } + print_to_console( + &print_lock, + Print::Error(format!("Error connecting: {}", err)), + ); + continue; } - print_to_console( - &print_lock, - Print::Error(format!("Error connecting: {}", err)), - ); - continue; } }; @@ -176,6 +183,7 @@ fn available_devices() -> Vec { .unwrap() .iter() .map(|p| p.port_name.clone()) + .chain(std::iter::once("stdio".into())) .collect() } @@ -228,7 +236,7 @@ fn disconnected( } fn perform_writes( - port: &mut BufReader>, + port: &mut BufReader, send_rx: &Receiver, raw_data_tx: &Sender, t_zero: Instant, @@ -251,11 +259,7 @@ fn perform_writes( } } -fn perform_reads( - port: &mut BufReader>, - raw_data_tx: &Sender, - t_zero: Instant, -) { +fn perform_reads(port: &mut BufReader, raw_data_tx: &Sender, t_zero: Instant) { let mut buf = "".to_string(); match serial_read(port, &mut buf) { Ok(_) => {