From 43200d273bbb9b19359e75209440f12bbd1b39b9 Mon Sep 17 00:00:00 2001 From: Jakob Klepp Date: Sun, 10 May 2020 22:30:38 +0200 Subject: [PATCH 1/4] Add serialport connection --- Cargo.lock | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 147 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8bc4e6e..2c88b8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,6 +27,24 @@ dependencies = [ "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bitflags" version = "1.2.1" @@ -42,6 +60,28 @@ name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "clap" +version = "2.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hermit-abi" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -148,6 +188,7 @@ dependencies = [ name = "serial_counter" version = "0.1.0" dependencies = [ + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "sdl2 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)", "serialport 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -168,6 +209,19 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "1.0.1" @@ -176,6 +230,16 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "void" version = "1.0.2" @@ -204,9 +268,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum CoreFoundation-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b" "checksum IOKit-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a" "checksum aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +"checksum hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" "checksum libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe" @@ -221,7 +289,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum sdl2 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6693f362118c0cd32858fe33a14d74cc3111bbc3a7de1aee88e5289fd9289f97" "checksum sdl2-sys 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)" = "575db20c45cce6565d4ece46509288ded53f5571dc89e4af165a562eb0eeec26" "checksum serialport 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8d3ecaf58010bedccae17be55d4ed6f2ecde5646fc48ce8c66ea2d35a1419c" +"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" +"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/Cargo.toml b/Cargo.toml index 4e9e916..7c98e4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +clap = "2.31.2" serialport = "3.3.0" [dependencies.sdl2] diff --git a/src/main.rs b/src/main.rs index ba5cd27..eb8c4fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,17 @@ +extern crate clap; extern crate sdl2; +extern crate serialport; + +use clap::{App, AppSettings, Arg}; use sdl2::pixels::Color; use sdl2::event::Event; use sdl2::keyboard::Keycode; use sdl2::rect::Rect; + +use serialport::prelude::*; + +use std::io::{self, Write}; use std::time::Duration; struct CounterApp { @@ -31,7 +39,62 @@ impl CounterApp { } } +fn print_all_ports() { + match serialport::available_ports() { + Ok(ports) => { + println!("Ports:"); + for port in ports { + println!("- {}", port.port_name); + } + }, + Err(err) => println!("Error {}", err), + }; +} + pub fn main() -> Result<(), String> { + let matches = App::new("Serialport Example - Receive Data") + .about("Reads data from a serial port and echoes it to stdout") + .setting(AppSettings::DisableVersion) + .arg( + Arg::with_name("port") + .help("The device path to a serial port") + .use_delimiter(false) + .required(true), + ) + .arg( + Arg::with_name("baud") + .help("The baud rate to connect at") + .use_delimiter(false) + .required(true), + ) + .get_matches(); + let port_name = matches.value_of("port").unwrap(); + let baud_rate = matches.value_of("baud").unwrap(); + + let mut settings: SerialPortSettings = Default::default(); + settings.timeout = Duration::from_millis(10); + if let Ok(rate) = baud_rate.parse::() { + settings.baud_rate = rate.into(); + } else { + eprintln!("Error: Invalid baud rate '{}' specified", baud_rate); + ::std::process::exit(1); + } + + let mut port = match serialport::open_with_settings(&port_name, &settings) { + Ok(mut _port) => _port, + Err(_e) => { + eprintln!("Failed to open \"{}\". Error: {}", port_name, _e); + ::std::process::exit(1); + } + }; + + let mut serial_buf: Vec = vec![0; 1000]; + println!("Receiving data on {} at {} baud:", &port_name, &baud_rate); + + + let port_name = matches.value_of("port").unwrap(); + let baud_rate = matches.value_of("baud").unwrap(); + let sdl_context = sdl2::init()?; let video_subsystem = sdl_context.video()?; @@ -39,7 +102,6 @@ pub fn main() -> Result<(), String> { let window = video_subsystem.window("rust-sdl2 demo: Video", 610, 320) .position_centered() - .opengl() .build() .map_err(|e| e.to_string())?; @@ -56,6 +118,11 @@ pub fn main() -> Result<(), String> { canvas.present(); let mut event_pump = sdl_context.event_pump()?; + print_all_ports(); + + //let port = serialport::open("/home/jakob/virtual-tty").unwrap(); + //println!("Connected to port: {}", port.name().unwrap()); + 'running: loop { for event in event_pump.poll_iter() { match event { @@ -66,6 +133,12 @@ pub fn main() -> Result<(), String> { } } + match port.read(serial_buf.as_mut_slice()) { + Ok(t) => io::stdout().write_all(&serial_buf[..t]).unwrap(), + Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), + Err(e) => eprintln!("{:?}", e), + } + canvas.clear(); canvas.set_draw_color(Color::WHITE); From ea6074649449d02144a3069dba01e9b61219fa62 Mon Sep 17 00:00:00 2001 From: Jakob Klepp Date: Mon, 11 May 2020 00:09:49 +0200 Subject: [PATCH 2/4] Command parsing --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 84 +++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c88b8f..d2e6b9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -189,6 +189,7 @@ name = "serial_counter" version = "0.1.0" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "sdl2 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)", "serialport 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index 7c98e4a..0eb729b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" [dependencies] clap = "2.31.2" +regex = "1.3.7" serialport = "3.3.0" [dependencies.sdl2] diff --git a/src/main.rs b/src/main.rs index eb8c4fe..69165c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,12 @@ extern crate clap; +extern crate regex; extern crate sdl2; extern crate serialport; use clap::{App, AppSettings, Arg}; +use regex::Regex; + use sdl2::pixels::Color; use sdl2::event::Event; use sdl2::keyboard::Keycode; @@ -51,7 +54,76 @@ fn print_all_ports() { }; } +enum CounterId { + Main, + CounterA, + CounterB, + CounterC, +} + +impl CounterId { + fn from_name(counter_name: &str) -> Result { + if counter_name == "counter_main" { + Ok(CounterId::Main) + } else if counter_name == "ctr_a" { + Ok(CounterId::CounterA) + } else if counter_name == "ctr_b" { + Ok(CounterId::CounterB) + } else if counter_name == "ctr_c" { + Ok(CounterId::CounterC) + } else { + Err(()) + } + } +} + +enum Command { + Increment { counter: CounterId, value: u32 }, + Decrement { counter: CounterId, value: u32 }, + Reset, + Invalid, +} + +fn parse_command(message: String) -> Command { + println!("Message: {}", message); + let re = Regex::new( + r"(?P(?Pctr_main|ctr_a|ctr_b|ctr_c)(?P\+|\-)(?P[1-9][0-9]*)|reset)" + ).unwrap(); + let caps = re.captures(message.as_str()).unwrap(); + if &caps["command"] == "reset" { + Command::Reset + } else if &caps["operation"] == "+" { + let value_str = &caps["value"]; + let counter_id_str = &caps["counter_name"]; + match (value_str.parse::(), CounterId::from_name(counter_id_str)) { + (Ok(value), Ok(counter_id)) => { + Command::Increment { + counter: counter_id, + value: value, + } + }, + _ => Command::Invalid + } + } else if &caps["operation"] == "-" { + let value_str = &caps["value"]; + let counter_id_str = &caps["counter_name"]; + match (value_str.parse::(), CounterId::from_name(counter_id_str)) { + (Ok(value), Ok(counter_id)) => { + Command::Decrement { + counter: counter_id, + value: value, + } + }, + _ => Command::Invalid + } + } else { + Command::Invalid + } +} + pub fn main() -> Result<(), String> { + print_all_ports(); + let matches = App::new("Serialport Example - Receive Data") .about("Reads data from a serial port and echoes it to stdout") .setting(AppSettings::DisableVersion) @@ -118,11 +190,6 @@ pub fn main() -> Result<(), String> { canvas.present(); let mut event_pump = sdl_context.event_pump()?; - print_all_ports(); - - //let port = serialport::open("/home/jakob/virtual-tty").unwrap(); - //println!("Connected to port: {}", port.name().unwrap()); - 'running: loop { for event in event_pump.poll_iter() { match event { @@ -134,7 +201,12 @@ pub fn main() -> Result<(), String> { } match port.read(serial_buf.as_mut_slice()) { - Ok(t) => io::stdout().write_all(&serial_buf[..t]).unwrap(), + Ok(t) => { + if let Ok(message) = std::str::from_utf8(&serial_buf) { + let cmd = parse_command(message.to_string()); + } + //io::stdout().write_all(&serial_buf[..t]).unwrap() + }, Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), Err(e) => eprintln!("{:?}", e), } From 59b985693d9d3daf579976e459efd5e4e11858d4 Mon Sep 17 00:00:00 2001 From: Jakob Klepp Date: Mon, 11 May 2020 00:12:59 +0200 Subject: [PATCH 3/4] Move function inside enum --- src/main.rs | 72 ++++++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/src/main.rs b/src/main.rs index 69165c0..cde8f29 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,6 +40,8 @@ impl CounterApp { self.ctr_b = 40; self.ctr_c = 40; } + + fn handle_command(cmd: Command) {} } fn print_all_ports() { @@ -84,40 +86,42 @@ enum Command { Invalid, } -fn parse_command(message: String) -> Command { - println!("Message: {}", message); - let re = Regex::new( - r"(?P(?Pctr_main|ctr_a|ctr_b|ctr_c)(?P\+|\-)(?P[1-9][0-9]*)|reset)" - ).unwrap(); - let caps = re.captures(message.as_str()).unwrap(); - if &caps["command"] == "reset" { - Command::Reset - } else if &caps["operation"] == "+" { - let value_str = &caps["value"]; - let counter_id_str = &caps["counter_name"]; - match (value_str.parse::(), CounterId::from_name(counter_id_str)) { - (Ok(value), Ok(counter_id)) => { - Command::Increment { - counter: counter_id, - value: value, - } - }, - _ => Command::Invalid +impl Command { + fn parse_command(message: String) -> Command { + println!("Message: {}", message); + let re = Regex::new( + r"(?P(?Pctr_main|ctr_a|ctr_b|ctr_c)(?P\+|\-)(?P[1-9][0-9]*)|reset)" + ).unwrap(); + let caps = re.captures(message.as_str()).unwrap(); + if &caps["command"] == "reset" { + Command::Reset + } else if &caps["operation"] == "+" { + let value_str = &caps["value"]; + let counter_id_str = &caps["counter_name"]; + match (value_str.parse::(), CounterId::from_name(counter_id_str)) { + (Ok(value), Ok(counter_id)) => { + Command::Increment { + counter: counter_id, + value: value, + } + }, + _ => Command::Invalid + } + } else if &caps["operation"] == "-" { + let value_str = &caps["value"]; + let counter_id_str = &caps["counter_name"]; + match (value_str.parse::(), CounterId::from_name(counter_id_str)) { + (Ok(value), Ok(counter_id)) => { + Command::Decrement { + counter: counter_id, + value: value, + } + }, + _ => Command::Invalid + } + } else { + Command::Invalid } - } else if &caps["operation"] == "-" { - let value_str = &caps["value"]; - let counter_id_str = &caps["counter_name"]; - match (value_str.parse::(), CounterId::from_name(counter_id_str)) { - (Ok(value), Ok(counter_id)) => { - Command::Decrement { - counter: counter_id, - value: value, - } - }, - _ => Command::Invalid - } - } else { - Command::Invalid } } @@ -203,7 +207,7 @@ pub fn main() -> Result<(), String> { match port.read(serial_buf.as_mut_slice()) { Ok(t) => { if let Ok(message) = std::str::from_utf8(&serial_buf) { - let cmd = parse_command(message.to_string()); + let cmd = Command::parse_command(message.to_string()); } //io::stdout().write_all(&serial_buf[..t]).unwrap() }, From 890e525e5b86768b856b9a61ddc9af2895daee45 Mon Sep 17 00:00:00 2001 From: Jakob Klepp Date: Mon, 11 May 2020 01:24:39 +0200 Subject: [PATCH 4/4] Implement state handling --- src/commands.rs | 83 +++++++++++++++++++++++++++++++++++ src/counter_app.rs | 48 ++++++++++++++++++++ src/main.rs | 106 +++------------------------------------------ 3 files changed, 138 insertions(+), 99 deletions(-) create mode 100644 src/commands.rs create mode 100644 src/counter_app.rs diff --git a/src/commands.rs b/src/commands.rs new file mode 100644 index 0000000..710b60a --- /dev/null +++ b/src/commands.rs @@ -0,0 +1,83 @@ +extern crate regex; + +use regex::Regex; + +#[derive(Debug)] +pub enum CounterId { + Main, + CounterA, + CounterB, + CounterC, +} + +impl CounterId { + fn from_name(counter_name: &str) -> Result { + println!("from_name {}", counter_name); + if counter_name == "ctr_main" { + return Ok(CounterId::Main) + } + if counter_name == "ctr_a" { + return Ok(CounterId::CounterA) + } + if counter_name == "ctr_b" { + return Ok(CounterId::CounterB) + } + if counter_name == "ctr_c" { + return Ok(CounterId::CounterC) + } + Err(()) + } +} + +#[derive(Debug)] +pub enum Command { + Increment { + counter: CounterId, + value: i32, + }, + Decrement { + counter: CounterId, + value: i32, + }, + Reset, + Invalid, +} + +impl Command { + pub fn parse_command(message: String) -> Command { + println!("Message: {}", message); + let re = Regex::new( + r"(?P(?Pctr_main|ctr_a|ctr_b|ctr_c)(?P\+|\-)(?P[1-9][0-9]*)|reset)" + ).unwrap(); + let caps = re.captures(message.as_str()).unwrap(); + if &caps["command"] == "reset" { + Command::Reset + } else if &caps["operation"] == "+" { + let value_str = &caps["value"]; + let counter_id_str = &caps["counter_name"]; + match (value_str.parse::(), CounterId::from_name(counter_id_str)) { + (Ok(value), Ok(counter_id)) => { + Command::Increment { + counter: counter_id, + value: value, + } + }, + _ => Command::Invalid + } + } else if &caps["operation"] == "-" { + let value_str = &caps["value"]; + let counter_id_str = &caps["counter_name"]; + match (value_str.parse::(), CounterId::from_name(counter_id_str)) { + (Ok(value), Ok(counter_id)) => { + Command::Decrement { + counter: counter_id, + value: value, + } + }, + _ => Command::Invalid + } + } else { + Command::Invalid + } + } +} diff --git a/src/counter_app.rs b/src/counter_app.rs new file mode 100644 index 0000000..0d735c8 --- /dev/null +++ b/src/counter_app.rs @@ -0,0 +1,48 @@ +use super::commands::{Command, CounterId}; + +#[derive(Debug)] +pub struct CounterApp { + pub ctr_main: i32, + pub ctr_a: i32, + pub ctr_b: i32, + pub ctr_c: i32, +} + +impl CounterApp { + pub fn new() -> CounterApp { + CounterApp { + ctr_main: 40, + ctr_a: 0, + ctr_b: 0, + ctr_c: 0, + } + } + + pub fn reset(&mut self) { + self.ctr_main = 40; + self.ctr_a = 0; + self.ctr_b = 0; + self.ctr_c = 0; + } + + fn add(&mut self, counter: CounterId, value: i32) { + println!("Counter {:?}", counter); + match counter { + CounterId::Main => (), + CounterId::CounterA => self.ctr_a += value, + CounterId::CounterB => self.ctr_b += value, + CounterId::CounterC => self.ctr_c += value, + }; + self.ctr_main -= value; + } + + pub fn handle_command(&mut self, cmd: Command) { + println!("App: {:?} Command {:?}", self, cmd); + match cmd { + Command::Increment { counter, value } => self.add(counter, value), + Command::Decrement { counter, value } => self.add(counter, -value), + Command::Reset => self.reset(), + Invalid => (), + }; + } +} diff --git a/src/main.rs b/src/main.rs index cde8f29..e2f7575 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ extern crate clap; -extern crate regex; extern crate sdl2; extern crate serialport; @@ -17,32 +16,8 @@ use serialport::prelude::*; use std::io::{self, Write}; use std::time::Duration; -struct CounterApp { - ctr_main: i32, - ctr_a: u8, - ctr_b: u8, - ctr_c: u8, -} - -impl CounterApp { - fn new() -> CounterApp { - CounterApp { - ctr_main: 40, - ctr_a: 0, - ctr_b: 0, - ctr_c: 0, - } - } - - fn reset(&mut self) { - self.ctr_main = 40; - self.ctr_a = 40; - self.ctr_b = 40; - self.ctr_c = 40; - } - - fn handle_command(cmd: Command) {} -} +mod commands; +mod counter_app; fn print_all_ports() { match serialport::available_ports() { @@ -56,76 +31,7 @@ fn print_all_ports() { }; } -enum CounterId { - Main, - CounterA, - CounterB, - CounterC, -} - -impl CounterId { - fn from_name(counter_name: &str) -> Result { - if counter_name == "counter_main" { - Ok(CounterId::Main) - } else if counter_name == "ctr_a" { - Ok(CounterId::CounterA) - } else if counter_name == "ctr_b" { - Ok(CounterId::CounterB) - } else if counter_name == "ctr_c" { - Ok(CounterId::CounterC) - } else { - Err(()) - } - } -} - -enum Command { - Increment { counter: CounterId, value: u32 }, - Decrement { counter: CounterId, value: u32 }, - Reset, - Invalid, -} - -impl Command { - fn parse_command(message: String) -> Command { - println!("Message: {}", message); - let re = Regex::new( - r"(?P(?Pctr_main|ctr_a|ctr_b|ctr_c)(?P\+|\-)(?P[1-9][0-9]*)|reset)" - ).unwrap(); - let caps = re.captures(message.as_str()).unwrap(); - if &caps["command"] == "reset" { - Command::Reset - } else if &caps["operation"] == "+" { - let value_str = &caps["value"]; - let counter_id_str = &caps["counter_name"]; - match (value_str.parse::(), CounterId::from_name(counter_id_str)) { - (Ok(value), Ok(counter_id)) => { - Command::Increment { - counter: counter_id, - value: value, - } - }, - _ => Command::Invalid - } - } else if &caps["operation"] == "-" { - let value_str = &caps["value"]; - let counter_id_str = &caps["counter_name"]; - match (value_str.parse::(), CounterId::from_name(counter_id_str)) { - (Ok(value), Ok(counter_id)) => { - Command::Decrement { - counter: counter_id, - value: value, - } - }, - _ => Command::Invalid - } - } else { - Command::Invalid - } - } -} - -pub fn main() -> Result<(), String> { +fn main() -> Result<(), String> { print_all_ports(); let matches = App::new("Serialport Example - Receive Data") @@ -181,7 +87,7 @@ pub fn main() -> Result<(), String> { .build() .map_err(|e| e.to_string())?; - let mut counter_app = CounterApp::new(); + let mut counter_app = counter_app::CounterApp::new(); let mut canvas = window.into_canvas().build().map_err(|e| e.to_string())?; @@ -207,7 +113,9 @@ pub fn main() -> Result<(), String> { match port.read(serial_buf.as_mut_slice()) { Ok(t) => { if let Ok(message) = std::str::from_utf8(&serial_buf) { - let cmd = Command::parse_command(message.to_string()); + let cmd = commands::Command::parse_command(message.to_string()); + println!("cmd {:?}", cmd); + counter_app.handle_command(cmd); } //io::stdout().write_all(&serial_buf[..t]).unwrap() },