diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2018-12-29 02:23:56 +0100 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2018-12-29 02:23:56 +0100 |
| commit | 72e712189ba8d65b9cce1da1fae6aa8b8727c3e2 (patch) | |
| tree | 0b334dafaf50c5a6a190a80b407f8f6942512775 | |
| parent | ab8eea8c95a63d659783969b3e367f0726764af4 (diff) | |
Program logic has been distributed from main to app and cmdline.
| -rw-r--r-- | Cargo.toml | 4 | ||||
| -rw-r--r-- | src/app.rs | 42 | ||||
| -rw-r--r-- | src/cmdline.rs | 138 | ||||
| -rw-r--r-- | src/main.rs | 211 |
4 files changed, 209 insertions, 186 deletions
@@ -1,7 +1,7 @@ [package] name = "rspsxserial" -version = "0.1.0" -authors = ["Xavier ASUS <xavi92psx@gmail.com>"] +version = "0.0.1" +authors = ["Xavier Del Campo <xavi92psx@gmail.com>"] [dependencies] serial = "0.4.0" diff --git a/src/app.rs b/src/app.rs new file mode 100644 index 0000000..95327fc --- /dev/null +++ b/src/app.rs @@ -0,0 +1,42 @@ +use std::{string::String, io, collections::HashMap}; + +/// This function is called once all command line a +/// rguments have been successfully parsed, and tries +/// to establish a TCP connection against a front-end +/// if configured by command line parameters. +pub fn app(arg_hash: HashMap<String, String>) -> io::Result<()> { + + let tcp = arg_hash.get(&String::from("--tcp")); + + match tcp { + None => println!("No TCP address specified"), + Some(addr) => setup_tcp(addr)? + }; + + Ok(()) +} + +fn setup_tcp(tcp_addr : &String) -> io::Result<()> { + + use std::net::{TcpListener}; + + let listener = TcpListener::bind(tcp_addr)?; + + println!("Awaiting for connection on address {}", tcp_addr); + + for stream in listener.incoming() { + match stream { + Ok(s) => { + // do something with the TcpStream + } + Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { + // wait until network socket is ready, typically implemented + // via platform-specific APIs such as epoll or IOCP + continue; + } + Err(e) => panic!("encountered IO error: {}", e), + } + } + + Ok(()) +} diff --git a/src/cmdline.rs b/src/cmdline.rs new file mode 100644 index 0000000..d3af076 --- /dev/null +++ b/src/cmdline.rs @@ -0,0 +1,138 @@ +use std::{string::String, env, collections::HashMap}; + +pub struct CmdLineArg { + pub arg_str : &'static str, + pub param_str : Option<&'static str>, + is_required : bool, + explanation : &'static str +} + +pub const CMD_LINE_ARGS : [CmdLineArg; 4] = +[ + CmdLineArg { + arg_str : "--port-name", + param_str : Some("[PORT]"), + is_required : true, + explanation : "Sets serial port" + }, + + CmdLineArg { + arg_str : "--disable-output", + param_str : None, + is_required : false, + explanation : "Disables incoming debug messages from the console" + }, + + CmdLineArg { + arg_str : "--baudrate", + param_str : Some("[BAUDRATE]"), + is_required : false, + explanation : "Sets serial port baudrate. Defaults to 4800bps" + }, + + CmdLineArg { + arg_str : "--tcp", + param_str : Some("[IPv4:PORT]"), + is_required : false, + explanation : "Sets a TCP connection against a compatible \ + front-end application" + } +]; + +fn show_help() { + println!("rspsxserial command line arguments:"); + + for arg in CMD_LINE_ARGS.iter() { + let line = format!("{} {}\t{}.", + arg.arg_str, + match arg.param_str { + None => "", + Some(param_str) => param_str + }, + arg.explanation); + + println!("{}", line); + } +} + +pub fn process_arguments() -> Option<HashMap<String, String>> { + + if env::args_os().count() <= 1 { + // Invalid number of command line arguments. + // Show default help dialog. + show_help(); + return None; + } + + // This enum defines a finite-state machine that + // will be used to determine what type of data is + // being retrieved + enum ExpectedParameter + { + ParameterOption, + ParameterValue + }; + + let mut parameter_state = ExpectedParameter::ParameterOption; + + let mut arg_hash: HashMap<String, String> = HashMap::new(); + let mut parameter_name = String::new(); + + for arg in env::args_os().skip(1) { + let arg_str = arg.into_string().unwrap(); + + match parameter_state { + ExpectedParameter::ParameterOption => { + if arg_str.starts_with("--") + { + // Looks like a valid parameter + + for param in CMD_LINE_ARGS.iter() { + + if arg_str == param.arg_str.to_string() { + parameter_name = arg_str; + + match param.param_str { + None => { + arg_hash.insert(parameter_name.clone(), String::from("")); + parameter_state = ExpectedParameter::ParameterOption; + } + + Some(_) => { + parameter_state = ExpectedParameter::ParameterValue; + } + } + + break; + } + } + } + else + { + return None; + } + }, + + ExpectedParameter::ParameterValue => { + let parameter_value = arg_str; + + arg_hash.insert(parameter_name.clone(), parameter_value.clone()); + parameter_state = ExpectedParameter::ParameterOption; + } + } + } + + // Check all needed parameters have been given + for arg in CMD_LINE_ARGS.iter() { + if arg.is_required { + let arg_string = arg.arg_str.to_string(); + + if !arg_hash.contains_key(&arg_string) { + println!("Missing required option {}", arg_string); + return None + } + } + } + + Some(arg_hash) +} diff --git a/src/main.rs b/src/main.rs index df51d84..3c49926 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,199 +1,42 @@ -extern crate serial; -use serial::prelude::*; +//~ extern crate serial; +//~ use serial::prelude::*; -use std::{string::String, env, io, collections::HashMap, time::Duration}; +mod cmdline; +mod app; /// Main function. fn main() { - - let arg_hash: Option<HashMap<String, String>> = process_arguments(); - // Read command line arguments. - match arg_hash { + match cmdline::process_arguments() { None => return, - _ => app(arg_hash.unwrap()) - } -} - -fn app(arg_hash: HashMap<String, String>) { - println!("App!"); -} - -struct CmdLineArg { - arg_str : &'static str, - param_str : Option<&'static str>, - is_required : bool, - explanation : &'static str -} - -impl CmdLineArg { - fn get_explanation(&self) -> String { - self.explanation.to_string() - } - - fn get_string(&self) -> String { - self.arg_str.to_string() - } - - fn get_param(&self) -> Option<String> { - match self.param_str { - None => None, - _ => Some(self.param_str.unwrap().to_string()) - } - } - - fn has_parameters(&self) -> bool { - match self.param_str { - None => false, - _ => true - } - } -} - -const CMD_LINE_ARGS : [CmdLineArg; 3] = -[ - CmdLineArg { - arg_str : "--port-name", - param_str : Some("[PORT]"), - is_required : true, - explanation : "Sets serial port" - }, - - CmdLineArg { - arg_str : "--disable-output", - param_str : None, - is_required : false, - explanation : "Disables incoming debug messages from the console" - }, - - CmdLineArg { - arg_str : "--baudrate", - param_str : Some("[BAUDRATE]"), - is_required : false, - explanation : "Sets serial port baudrate. Defaults to 4800bps" - } -]; - -fn show_help() { - println!("rspsxserial command line arguments:"); - - for arg in CMD_LINE_ARGS.iter() { - let mut line = String::new(); - - line.push_str(arg.arg_str); - - if arg.has_parameters() { - line.push(' '); - line.push_str(arg.param_str.unwrap()); - }; - - line.push('\t'); - line.push_str(arg.explanation); - line.push('.'); - - println!("{}", line); - } -} - -fn process_arguments() -> Option<HashMap<String, String>> { - - if env::args_os().count() <= 1 { - show_help(); - return None; - } - - enum ExpectedParameter - { - ParameterOption, - ParameterValue - }; - - let mut parameter_state = ExpectedParameter::ParameterOption; - - let mut arg_hash: HashMap<String, String> = HashMap::new(); - let mut parameter_name = String::new(); - - for arg in env::args_os().skip(1) { - let arg_str = arg.into_string().unwrap(); - - match parameter_state { - ExpectedParameter::ParameterOption => { - if arg_str.starts_with("--") - { - // Looks like a valid parameter - - for param in CMD_LINE_ARGS.iter() { - - if arg_str == param.arg_str.to_string() { - println!("Found valid parameter {}", arg_str); - parameter_name = arg_str; - - match param.param_str { - None => { - println!("This option uses no parameters"); - arg_hash.insert(parameter_name.clone(), String::from("")); - parameter_state = ExpectedParameter::ParameterOption; - } - - _ => { - parameter_state = ExpectedParameter::ParameterValue; - } - } - - break; - } - } - } - else - { - return None; - } - }, - - ExpectedParameter::ParameterValue => { - let parameter_value = arg_str; - - arg_hash.insert(parameter_name.clone(), parameter_value.clone()); - parameter_state = ExpectedParameter::ParameterOption; + Some(hash) => { + match app::app(hash) { + _ => return } } - } - - // Check all needed parameters have been given - for arg in CMD_LINE_ARGS.iter() { - if arg.is_required { - let arg_string = arg.arg_str.to_string(); - - if !arg_hash.contains_key(&arg_string) { - println!("Missing required option {}", arg_string); - return None - } - } - } - - Some(arg_hash) + }; } -/** let mut port = serial::open(&arg).unwrap(); - interact(&mut port).unwrap();*/ +//~ /** let mut port = serial::open(&arg).unwrap(); + //~ interact(&mut port).unwrap();*/ -/// This function reconfigures a serial port with default parameters -fn interact<T: SerialPort>(port: &mut T) -> io::Result<()> { - port.reconfigure(&|settings| { - settings.set_baud_rate(serial::Baud9600)?; - settings.set_char_size(serial::Bits8); - settings.set_parity(serial::ParityNone); - settings.set_stop_bits(serial::Stop1); - settings.set_flow_control(serial::FlowNone); - Ok(()) - })?; +//~ /// This function reconfigures a serial port with default parameters +//~ fn interact<T: SerialPort>(port: &mut T) -> io::Result<()> { + //~ port.reconfigure(&|settings| { + //~ settings.set_baud_rate(serial::Baud9600)?; + //~ settings.set_char_size(serial::Bits8); + //~ settings.set_parity(serial::ParityNone); + //~ settings.set_stop_bits(serial::Stop1); + //~ settings.set_flow_control(serial::FlowNone); + //~ Ok(()) + //~ })?; - port.set_timeout(Duration::from_millis(1000))?; + //~ port.set_timeout(Duration::from_millis(1000))?; - let buf: Vec<u8> = (0..255).collect(); + //~ let buf: Vec<u8> = (0..255).collect(); - port.write(&buf[..])?; - //port.read(&mut buf[..])?; + //~ port.write(&buf[..])?; + //~ //port.read(&mut buf[..])?; - Ok(()) -} + //~ Ok(()) +//~ } |
