Added coloured output and also removed hard-coded strings
authorHarishankar <v.harishankar@gmail.com>
Fri, 29 May 2020 15:23:57 +0000 (20:53 +0530)
committerHarishankar <v.harishankar@gmail.com>
Fri, 29 May 2020 15:47:39 +0000 (21:17 +0530)
Added colour to output using ansi_term crate and also removed
hardcoded strings from all over the input and replace them
with const

Cargo.lock
Cargo.toml
src/main.rs

index 1f7d091..9a08007 100644 (file)
@@ -9,10 +9,20 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "ansi_term"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
+dependencies = [
+ "winapi",
+]
+
 [[package]]
 name = "evpf"
 version = "0.1.0"
 dependencies = [
+ "ansi_term",
  "regex",
 ]
 
@@ -54,3 +64,25 @@ checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
 dependencies = [
  "lazy_static",
 ]
+
+[[package]]
+name = "winapi"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
index 8615725..c4e36c3 100644 (file)
@@ -8,3 +8,4 @@ edition = "2018"
 
 [dependencies]
 regex="1"
+ansi_term="0.12"
index c911ca2..bab1e52 100644 (file)
@@ -1,7 +1,27 @@
 use std::io;
 use std::io::Write;
 use regex::Regex;
+use ansi_term::Colour;
+use ansi_term::Style;
 
+const ILLEGAL_EXP : &'static str = "Illegal Expression";
+const ERR_PARSING_NOT_MATCH : &'static str = "Error parsing expression! \
+                                Must be a number or operator (+,-,* or /)";
+const ERR_POSTFIX_INCOMPLETE : &'static str = "Postfix expression incomplete!";
+const ERR_FLUSHING : &'static str = "Error flushing!";
+const ERR_READING_LINE : &'static str = "Error reading line!";
+const HELP_TEXT : [&str ; 4] = 
+                               ["Type an expression in postfix style to evaluate.",
+                                "Example: 4 5 + 12 -",
+                                "Supported operators: +, -, *, /",
+                                "Type q, Q to quit"
+                                ];
+
+const RESULT : &'static str = "Result";
+const ERROR : &'static str = "Error";
+const ERROR_HELP : &'static str = "Type ? or h or H for help";
+
+// Describe an operator - one of add, subtract, multiply or divide
 enum Operator { 
        ADD,
        SUB,
@@ -21,13 +41,13 @@ fn get_result (t : &mut Vec<Expression>, op : Operator) -> Result<f32,String> {
        // if nothing - panic with error
        let n1 = t.pop ();
        if n1.is_none () { 
-               return Err ("Illegal expression".to_string());
+               return Err (ILLEGAL_EXP.to_string());
        }
        // pop the stack for the first operand
        // if nothing - panic with error
        let n2 = t.pop ();
        if n2.is_none () {
-               return Err ("Illegal expression!".to_string());
+               return Err (ILLEGAL_EXP.to_string());
        }
        
        let num1 = n1.unwrap().value;
@@ -97,8 +117,7 @@ fn evaluate (expr : &str, match_num : &regex::Regex) -> Result<f32,String> {
                          }     
                        // if word doesn't match either operator or number then panic.                  
                        else {
-                               return Err ("Error parsing expression! \
-                                Must be a number or operator (+,-,* or /)".to_string());
+                               return Err (ERR_PARSING_NOT_MATCH.to_string());
                        }
                }
        }
@@ -106,7 +125,7 @@ fn evaluate (expr : &str, match_num : &regex::Regex) -> Result<f32,String> {
        if ops.len () > 1 {
        // if the stack has more than one value, it means that the postfix
        // expression is not complete - so display the stack status
-               return Err ("Postfix expression incomplete!".to_string());
+               return Err (ERR_POSTFIX_INCOMPLETE.to_string());
        } else { 
        // stack has only one item which is the result so display it
                let res = ops[0].value;
@@ -122,10 +141,10 @@ fn main() {
        // loop until a blank line is received  
        loop {
                expr.clear ();  
-               print!("evpf>");
-               io::stdout().flush ().expect ("Error flushing!");
+               print!("{}", Style::new().bold().paint("evpf>"));
+               io::stdout().flush ().expect (ERR_FLUSHING);
                // read a line of text
-               io::stdin().read_line (&mut expr).expect ("Error reading line!");
+               io::stdin().read_line (&mut expr).expect (ERR_READING_LINE);
                // trim the text
                let expr = expr.trim ();
 
@@ -134,23 +153,30 @@ fn main() {
                        break;
                } else if expr == "?" || expr == "h" || expr == "H" {
                // display help text
-                       println! ("Type an expression in postfix style to evaluate.");
-                       println! ("Example: 4 5 + 12 -");
-                       println! ("Supported operators: +, -, *, /");
-                       println! ("Type q, Q to quit");
+                       for text in HELP_TEXT.iter() {
+                               println! ("{}", Colour::Cyan.paint(*text));
+                       }
+
                        continue;
                } else if expr == "" {
                // continue without proceeding
                        continue;
                }
                
+               // Evaluate result
                let res = evaluate (&expr, &match_num);
+               
+               // if Result is OK then print the result in green
                if res.is_ok () {
-                       println! ("Result: {}", res.unwrap());
-               }
-               else {
-                       eprintln! ("Error: {}", res.unwrap_err());
-                       eprintln! ("Type ? or h or H for help");
+                       let restxt = format! ("{}: {}", RESULT, 
+                                                                                       res.unwrap());
+                       println! ("{}", Colour::Green.paint (restxt));
+               } else {
+               // print the error in purple
+                       let errtxt = format! ("{}: {}", ERROR, 
+                                                                                       res.unwrap_err());
+                       eprintln! ("{}", Colour::Purple.paint (errtxt));
+                       eprintln! ("{}", Colour::Purple.paint (ERROR_HELP));
                }
        }
 }