Minor error handling fixed
[evpf.git] / src / main.rs
index f46dfab..51ea94e 100644 (file)
@@ -2,6 +2,7 @@ use regex::Regex;
 use colored::*;
 use std::env;
 use rustyline::Editor;
+use std::path::PathBuf;
 
 const ILLEGAL_EXP : &'static str = "Illegal Expression";
 const ERR_PARSING_NOT_MATCH : &'static str = "Error parsing expression! \
@@ -13,6 +14,13 @@ const HELP_TEXT : [&str ; 4] =
                                 "Supported operators: +, -, *, /",
                                 "Type q, Q to quit"
                                 ];
+                                
+const HOMEDIR_NOT_FOUND : &'static str = "User home directory not found \
+                               (missing environment?).";
+                               
+const HISTORY_FILE_NOT_FOUND : &'static str = "History file not found.";
+
+const SAVE_HISTORY_ERROR : &'static str = "Unable to save command history!";
 
 const ERROR : &'static str = "Error";
 const ERROR_HELP : &'static str = "Type ? or h or H for help";
@@ -156,6 +164,30 @@ fn run_command_line (args : &Vec<String>, match_num : &regex::Regex) {
        }
 }
 
+// get the history file name as string - home dir + .evpfhistory
+fn get_history_file () -> Result<String,String> {
+       // get the environment variable HOME
+       let home_path = env::var ("HOME");
+       // if not found, return an error
+       if home_path.is_err () {
+               return Err (HOMEDIR_NOT_FOUND.to_string());
+       }
+       // build the path for the history file i.e. homedir + .evpfhistory in
+       // platform independent way
+       let mut hist_file = PathBuf::new ();
+       hist_file.push (home_path.unwrap());
+       hist_file.push (".evpfhistory");        
+       
+       // if cannot convert to string return error 
+       if hist_file.to_str ().is_none () {
+               return Err (HOMEDIR_NOT_FOUND.to_string());
+       }
+       
+       // return the history file path as a string
+       let hist_file_path = String::from (hist_file.to_str().unwrap());
+       return Ok (hist_file_path);
+}
+
 // Interactive mode - display the prompt and evaluate expressions entered into
 // the prompt - until user quits
 fn run_interactive_mode (match_num : &regex::Regex) {
@@ -163,6 +195,17 @@ fn run_interactive_mode (match_num : &regex::Regex) {
        let mut expr = String::new ();
 
        let mut rl = Editor::<()>::new ();
+       
+       // load the history file
+       let hist_file = get_history_file ();
+       // if unable to load the history file, display the appropriate error
+       if hist_file.is_err () {
+               eprintln! ("{}", &hist_file.unwrap_err());
+       } else {
+               if rl.load_history (&hist_file.unwrap ()).is_err () {
+                       eprintln! ("{}", HISTORY_FILE_NOT_FOUND.purple());
+               }
+       }
        // loop until a blank line is received  
        loop {
                expr.clear ();
@@ -205,13 +248,22 @@ fn run_interactive_mode (match_num : &regex::Regex) {
                        eprintln! ("{}", ERROR_HELP.purple());
                }
        }
+       // save the history 
+       let hist_file = get_history_file ();
+       if ! hist_file.is_err () {
+               if rl.save_history (&hist_file.unwrap()).is_err () {
+                       eprintln! ("{}", SAVE_HISTORY_ERROR);
+               }
+       } else {
+               eprintln! ("{}", &hist_file.unwrap_err());
+       }
 }
 
 fn main() {
        // collect the command line arguments - if any 
        let args : Vec<String> = env::args().collect ();
        // regular expression to match a number 
-       let match_num = Regex::new (r"^\d+?\.*?\d*?$").unwrap ();
+       let match_num = Regex::new (r"^\-?\d+?\.*?\d*?$").unwrap ();
        
        if args.len () > 1 {
        // if arguments are provided run in command line mode - i.e. print the