From 4f82f8ace749f5ffee1b0673ef3d768fcdce8547 Mon Sep 17 00:00:00 2001 From: Valerie Date: Mon, 13 Jun 2022 00:50:14 -0400 Subject: [PATCH] cleaned up hex converter and added binary & octal ones, added exit keyword --- src/helper.rs | 42 +++++++++++++++++++++++++----------------- src/main.rs | 9 +++++++-- src/util.rs | 18 ++++++++++++++++++ 3 files changed, 50 insertions(+), 19 deletions(-) create mode 100644 src/util.rs diff --git a/src/helper.rs b/src/helper.rs index 0a20097..417a6b9 100644 --- a/src/helper.rs +++ b/src/helper.rs @@ -4,6 +4,8 @@ use evalexpr::{ EvalexprError }; +use crate::util; + pub fn average(arg: &Value) -> Result { let arguments = arg.as_tuple()?; let count = arguments.len() as i64; @@ -43,23 +45,29 @@ pub fn average(arg: &Value) -> Result { } } -pub fn hex(arg: &Value) -> Option { +pub fn binary(arg: &Value) -> Result { if !arg.is_string() { - if arg.is_int() { - let num = arg.as_int().ok().unwrap(); - let fmt = format!("0x{:X}", num); - return Some(fmt.into()); - } - return None; + let num = arg.as_int()?; + let fmt = format!("0b{:b}", num); + return Ok(fmt.into()); } - let i_parse = arg.as_string().ok().unwrap(); - let parse = i_parse.strip_prefix("0x").unwrap_or(i_parse.as_str()); - - let i_result = i64::from_str_radix(parse, 16); - if i_result.is_err() { return None; } - let result: Option = i_result.ok(); - if result.is_none() { return None; } - - let output: Value = result.unwrap().into(); - return Some(output); + util::parse_radix("0b", 2, arg) +} + +pub fn hexadecimal(arg: &Value) -> Result { + if !arg.is_string() { + let num = arg.as_int()?; + let fmt = format!("0x{:X}", num); + return Ok(fmt.into()); + } + util::parse_radix("0x", 16, arg) +} + +pub fn octal(arg: &Value) -> Result { + if !arg.is_string() { + let num = arg.as_int()?; + let fmt = format!("{:#o}", num); + return Ok(fmt.into()); + } + util::parse_radix("0o", 8, arg) } diff --git a/src/main.rs b/src/main.rs index fedf5ea..9526ce6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,13 +22,18 @@ use termion::{ }; mod helper; +mod util; pub const VERSION: &str = "0.1.4"; fn main() { let mut context = context_map! { "avg" => Function::new(|arg| helper::average(arg)), - "hex" => Function::new(|arg| Ok(helper::hex(arg).unwrap_or(0.into()))) + + // radix functions + "bin" => Function::new(|arg| helper::binary(arg)), + "hex" => Function::new(|arg| helper::hexadecimal(arg)), + "oct" => Function::new(|arg| helper::octal(arg)) }.unwrap(); let expressions: Vec = env::args().skip(1).collect(); if expressions.len() == 0 { @@ -42,7 +47,7 @@ fn main() { break; } let line = i_line.trim().to_string(); - if line.is_empty() { + if line.is_empty() || line == "exit" { break; } let result = do_eval(line, &mut context); diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..1cc557e --- /dev/null +++ b/src/util.rs @@ -0,0 +1,18 @@ +use evalexpr::{ + Value, + + EvalexprError +}; + +pub(crate) fn parse_radix(prefix: &str, base: u32, arg: &Value) -> Result { + let i_parse = arg.as_string()?; + let parse = i_parse.strip_prefix(prefix).unwrap_or(i_parse.as_str()); + + let i_result = i64::from_str_radix(parse, base); + if i_result.is_err() { + return Err(EvalexprError::CustomMessage("failed to parse integer from string".to_string())); + } + let result = i_result.ok(); + + return Ok(result.unwrap().into()); +}