From dbb731687b77e26d2ff120a699aeff5fa0629f35 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Sat, 21 Oct 2023 22:05:04 +0200 Subject: [PATCH 1/3] Allow using stdio as a 'Device' --- src/main.rs | 9 ++-- src/serial.rs | 60 ++++++++++++++---------- src/stdio.rs | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 31 deletions(-) create mode 100644 src/stdio.rs diff --git a/src/main.rs b/src/main.rs index 043a354..0dd8071 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ mod data; mod gui; mod io; mod serial; +mod stdio; mod toggle; const APP_INFO: AppInfo = AppInfo { @@ -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..e80a273 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use serialport::{DataBits, FlowControl, Parity, SerialPort, StopBits}; use crate::data::{get_epoch_ms, SerialDirection}; -use crate::{print_to_console, Packet, Print, APP_INFO, PREFS_KEY_SERIAL}; +use crate::{print_to_console, stdio, Packet, Print, APP_INFO, PREFS_KEY_SERIAL}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SerialDevices { @@ -112,32 +112,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(Box::new(stdio::Stdio) as _) + } 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(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 +185,7 @@ fn available_devices() -> Vec { .unwrap() .iter() .map(|p| p.port_name.clone()) + .chain(std::iter::once("stdio".into())) .collect() } diff --git a/src/stdio.rs b/src/stdio.rs new file mode 100644 index 0000000..112664b --- /dev/null +++ b/src/stdio.rs @@ -0,0 +1,124 @@ +use std::{io, time}; + +pub struct Stdio; + +impl serialport::SerialPort for Stdio { + fn name(&self) -> Option { + todo!() + } + + fn baud_rate(&self) -> serialport::Result { + todo!() + } + + fn data_bits(&self) -> serialport::Result { + todo!() + } + + fn flow_control(&self) -> serialport::Result { + todo!() + } + + fn parity(&self) -> serialport::Result { + todo!() + } + + fn stop_bits(&self) -> serialport::Result { + todo!() + } + + fn timeout(&self) -> time::Duration { + todo!() + } + + fn set_baud_rate(&mut self, _baud_rate: u32) -> serialport::Result<()> { + todo!() + } + + fn set_data_bits(&mut self, _data_bits: serialport::DataBits) -> serialport::Result<()> { + todo!() + } + + fn set_flow_control( + &mut self, + _flow_control: serialport::FlowControl, + ) -> serialport::Result<()> { + todo!() + } + + fn set_parity(&mut self, _parity: serialport::Parity) -> serialport::Result<()> { + todo!() + } + + fn set_stop_bits(&mut self, _stop_bits: serialport::StopBits) -> serialport::Result<()> { + todo!() + } + + fn set_timeout(&mut self, _timeout: time::Duration) -> serialport::Result<()> { + todo!() + } + + fn write_request_to_send(&mut self, _level: bool) -> serialport::Result<()> { + todo!() + } + + fn write_data_terminal_ready(&mut self, _level: bool) -> serialport::Result<()> { + todo!() + } + + fn read_clear_to_send(&mut self) -> serialport::Result { + todo!() + } + + fn read_data_set_ready(&mut self) -> serialport::Result { + todo!() + } + + fn read_ring_indicator(&mut self) -> serialport::Result { + todo!() + } + + fn read_carrier_detect(&mut self) -> serialport::Result { + todo!() + } + + fn bytes_to_read(&self) -> serialport::Result { + todo!() + } + + fn bytes_to_write(&self) -> serialport::Result { + todo!() + } + + fn clear(&self, _buffer_to_clear: serialport::ClearBuffer) -> serialport::Result<()> { + todo!() + } + + fn try_clone(&self) -> serialport::Result> { + todo!() + } + + fn set_break(&self) -> serialport::Result<()> { + todo!() + } + + fn clear_break(&self) -> serialport::Result<()> { + todo!() + } +} + +impl io::Write for Stdio { + fn write(&mut self, buf: &[u8]) -> io::Result { + io::stdout().write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + io::stdout().flush() + } +} + +impl io::Read for Stdio { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + io::stdin().read(buf) + } +} From 979803b1edce3df84017be3b2495fb58cd5e570e Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Thu, 26 Oct 2023 20:25:55 +0200 Subject: [PATCH 2/3] Add type DataSource to better handle serial port and stdio --- src/main.rs | 2 +- src/serial.rs | 26 ++++------- src/stdio.rs | 124 -------------------------------------------------- 3 files changed, 11 insertions(+), 141 deletions(-) delete mode 100644 src/stdio.rs diff --git a/src/main.rs b/src/main.rs index 0dd8071..9cdc595 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,10 +21,10 @@ use crate::io::{save_to_csv, FileOptions}; use crate::serial::{load_serial_settings, serial_thread, Device}; mod data; +mod data_source; mod gui; mod io; mod serial; -mod stdio; mod toggle; const APP_INFO: AppInfo = AppInfo { diff --git a/src/serial.rs b/src/serial.rs index e80a273..4792a6b 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -1,14 +1,15 @@ -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::{print_to_console, stdio, Packet, Print, APP_INFO, PREFS_KEY_SERIAL}; +use crate::data_source::DataSource; +use crate::{print_to_console, Packet, Print, APP_INFO, PREFS_KEY_SERIAL}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SerialDevices { @@ -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) @@ -118,7 +116,7 @@ pub fn serial_thread( } print_to_console(&print_lock, Print::Ok(format!("Connected to stdio"))); - BufReader::new(Box::new(stdio::Stdio) as _) + BufReader::new(DataSource::Stdio) } else { match serialport::new(&device.name, device.baud_rate) .timeout(Duration::from_millis(100)) @@ -135,7 +133,7 @@ pub fn serial_thread( device.name, device.baud_rate )), ); - BufReader::new(p) + BufReader::new(DataSource::SerialPort(p)) } Err(err) => { if let Ok(mut write_guard) = device_lock.write() { @@ -238,7 +236,7 @@ fn disconnected( } fn perform_writes( - port: &mut BufReader>, + port: &mut BufReader, send_rx: &Receiver, raw_data_tx: &Sender, t_zero: Instant, @@ -261,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(_) => { diff --git a/src/stdio.rs b/src/stdio.rs deleted file mode 100644 index 112664b..0000000 --- a/src/stdio.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::{io, time}; - -pub struct Stdio; - -impl serialport::SerialPort for Stdio { - fn name(&self) -> Option { - todo!() - } - - fn baud_rate(&self) -> serialport::Result { - todo!() - } - - fn data_bits(&self) -> serialport::Result { - todo!() - } - - fn flow_control(&self) -> serialport::Result { - todo!() - } - - fn parity(&self) -> serialport::Result { - todo!() - } - - fn stop_bits(&self) -> serialport::Result { - todo!() - } - - fn timeout(&self) -> time::Duration { - todo!() - } - - fn set_baud_rate(&mut self, _baud_rate: u32) -> serialport::Result<()> { - todo!() - } - - fn set_data_bits(&mut self, _data_bits: serialport::DataBits) -> serialport::Result<()> { - todo!() - } - - fn set_flow_control( - &mut self, - _flow_control: serialport::FlowControl, - ) -> serialport::Result<()> { - todo!() - } - - fn set_parity(&mut self, _parity: serialport::Parity) -> serialport::Result<()> { - todo!() - } - - fn set_stop_bits(&mut self, _stop_bits: serialport::StopBits) -> serialport::Result<()> { - todo!() - } - - fn set_timeout(&mut self, _timeout: time::Duration) -> serialport::Result<()> { - todo!() - } - - fn write_request_to_send(&mut self, _level: bool) -> serialport::Result<()> { - todo!() - } - - fn write_data_terminal_ready(&mut self, _level: bool) -> serialport::Result<()> { - todo!() - } - - fn read_clear_to_send(&mut self) -> serialport::Result { - todo!() - } - - fn read_data_set_ready(&mut self) -> serialport::Result { - todo!() - } - - fn read_ring_indicator(&mut self) -> serialport::Result { - todo!() - } - - fn read_carrier_detect(&mut self) -> serialport::Result { - todo!() - } - - fn bytes_to_read(&self) -> serialport::Result { - todo!() - } - - fn bytes_to_write(&self) -> serialport::Result { - todo!() - } - - fn clear(&self, _buffer_to_clear: serialport::ClearBuffer) -> serialport::Result<()> { - todo!() - } - - fn try_clone(&self) -> serialport::Result> { - todo!() - } - - fn set_break(&self) -> serialport::Result<()> { - todo!() - } - - fn clear_break(&self) -> serialport::Result<()> { - todo!() - } -} - -impl io::Write for Stdio { - fn write(&mut self, buf: &[u8]) -> io::Result { - io::stdout().write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - io::stdout().flush() - } -} - -impl io::Read for Stdio { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - io::stdin().read(buf) - } -} From 75bc6707e97ba293419e8e939eb74b6540a090bb Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Thu, 26 Oct 2023 20:34:34 +0200 Subject: [PATCH 3/3] Use suggested name 'Interface' --- src/interface.rs | 31 +++++++++++++++++++++++++++++++ src/main.rs | 2 +- src/serial.rs | 14 +++++++------- 3 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 src/interface.rs 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 9cdc595..413dae5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,8 +21,8 @@ use crate::io::{save_to_csv, FileOptions}; use crate::serial::{load_serial_settings, serial_thread, Device}; mod data; -mod data_source; mod gui; +mod interface; mod io; mod serial; mod toggle; diff --git a/src/serial.rs b/src/serial.rs index 4792a6b..85e6f6d 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use serialport::{DataBits, FlowControl, Parity, StopBits}; use crate::data::{get_epoch_ms, SerialDirection}; -use crate::data_source::DataSource; +use crate::interface::Interface; use crate::{print_to_console, Packet, Print, APP_INFO, PREFS_KEY_SERIAL}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -75,13 +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) @@ -116,7 +116,7 @@ pub fn serial_thread( } print_to_console(&print_lock, Print::Ok(format!("Connected to stdio"))); - BufReader::new(DataSource::Stdio) + BufReader::new(Interface::Stdio) } else { match serialport::new(&device.name, device.baud_rate) .timeout(Duration::from_millis(100)) @@ -133,7 +133,7 @@ pub fn serial_thread( device.name, device.baud_rate )), ); - BufReader::new(DataSource::SerialPort(p)) + BufReader::new(Interface::SerialPort(p)) } Err(err) => { if let Ok(mut write_guard) = device_lock.write() { @@ -236,7 +236,7 @@ fn disconnected( } fn perform_writes( - port: &mut BufReader, + port: &mut BufReader, send_rx: &Receiver, raw_data_tx: &Sender, t_zero: Instant, @@ -259,7 +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(_) => {