diff --git a/Cargo.lock b/Cargo.lock index c98c088..e7d21b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,6 +75,7 @@ dependencies = [ name = "localdeck-keyboard" version = "0.1.0" dependencies = [ + "once_cell", "regex", "serialport", ] @@ -105,6 +106,12 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + [[package]] name = "pkg-config" version = "0.3.30" diff --git a/Cargo.toml b/Cargo.toml index d929d5e..90a3f99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,5 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] +once_cell = "1.19.0" regex = "1.10.6" serialport = "4.5.1" diff --git a/src/main.rs b/src/main.rs index db0d7f6..e6eb00f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,12 @@ +use once_cell::sync::Lazy; use regex::Regex; use serialport::{SerialPort, SerialPortInfo, SerialPortType}; -use std::io::{BufRead, BufReader}; +use std::io::{BufRead, BufReader, ErrorKind as IOErrorKind, Result as IOResult}; use std::time::Duration; // My dev board - final might be different const VID_PID: (u16, u16) = (0x303a, 0x1001); +static KEY_RE: Lazy = Lazy::new(|| Regex::new(r"key '(?P[A-Z])' pressed").unwrap()); fn get_board_port() -> Option { let ports = serialport::available_ports().expect("No ports found!"); @@ -19,18 +21,23 @@ fn get_board_port() -> Option { None } -fn get_keys(conn: Box) -> impl Iterator { - let reader = BufReader::new(conn); - let key_re = Regex::new(r"key '(?P[A-Z])' pressed").unwrap(); +fn key_from_line(line: String) -> Option { + KEY_RE + .captures(&line) + .and_then(|captures| captures.name("key")) + .map(|k| String::from(k.as_str())) +} - reader.lines().filter_map(move |l| { - if let Ok(msg) = l { - return key_re - .captures(&msg) - .and_then(|captures| captures.name("key")) - .map(|k| String::from(k.as_str())); - } - None +fn get_keys(conn: Box) -> impl Iterator> { + let reader = BufReader::new(conn); + + reader.lines().filter_map(|l| match l { + // Discard timeouts + Err(e) if e.kind() == IOErrorKind::TimedOut => None, + + Err(_) => Some(l), + + Ok(s) => key_from_line(s).map(Ok), }) } @@ -49,7 +56,10 @@ fn main() { .open() .unwrap(); - for key in get_keys(conn) { - println!("Key pressed: {}", key); + for maybe_key in get_keys(conn) { + match maybe_key { + Ok(key) => println!("Key pressed: {}", key), + Err(e) => println!("Error: {:?}", e), + } } }