cleaned up hex converter and added binary & octal ones, added exit keyword

This commit is contained in:
Valerie Wolfe 2022-06-13 00:50:14 -04:00
parent e241b824cc
commit 4f82f8ace7
3 changed files with 50 additions and 19 deletions

View file

@ -4,6 +4,8 @@ use evalexpr::{
EvalexprError EvalexprError
}; };
use crate::util;
pub fn average(arg: &Value) -> Result<Value, EvalexprError> { pub fn average(arg: &Value) -> Result<Value, EvalexprError> {
let arguments = arg.as_tuple()?; let arguments = arg.as_tuple()?;
let count = arguments.len() as i64; let count = arguments.len() as i64;
@ -43,23 +45,29 @@ pub fn average(arg: &Value) -> Result<Value, EvalexprError> {
} }
} }
pub fn hex(arg: &Value) -> Option<Value> { pub fn binary(arg: &Value) -> Result<Value, EvalexprError> {
if !arg.is_string() { if !arg.is_string() {
if arg.is_int() { let num = arg.as_int()?;
let num = arg.as_int().ok().unwrap(); let fmt = format!("0b{:b}", num);
let fmt = format!("0x{:X}", num); return Ok(fmt.into());
return Some(fmt.into());
}
return None;
} }
let i_parse = arg.as_string().ok().unwrap(); util::parse_radix("0b", 2, arg)
let parse = i_parse.strip_prefix("0x").unwrap_or(i_parse.as_str()); }
let i_result = i64::from_str_radix(parse, 16); pub fn hexadecimal(arg: &Value) -> Result<Value, EvalexprError> {
if i_result.is_err() { return None; } if !arg.is_string() {
let result: Option<i64> = i_result.ok(); let num = arg.as_int()?;
if result.is_none() { return None; } let fmt = format!("0x{:X}", num);
return Ok(fmt.into());
let output: Value = result.unwrap().into(); }
return Some(output); util::parse_radix("0x", 16, arg)
}
pub fn octal(arg: &Value) -> Result<Value, EvalexprError> {
if !arg.is_string() {
let num = arg.as_int()?;
let fmt = format!("{:#o}", num);
return Ok(fmt.into());
}
util::parse_radix("0o", 8, arg)
} }

View file

@ -22,13 +22,18 @@ use termion::{
}; };
mod helper; mod helper;
mod util;
pub const VERSION: &str = "0.1.4"; pub const VERSION: &str = "0.1.4";
fn main() { fn main() {
let mut context = context_map! { let mut context = context_map! {
"avg" => Function::new(|arg| helper::average(arg)), "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(); }.unwrap();
let expressions: Vec<String> = env::args().skip(1).collect(); let expressions: Vec<String> = env::args().skip(1).collect();
if expressions.len() == 0 { if expressions.len() == 0 {
@ -42,7 +47,7 @@ fn main() {
break; break;
} }
let line = i_line.trim().to_string(); let line = i_line.trim().to_string();
if line.is_empty() { if line.is_empty() || line == "exit" {
break; break;
} }
let result = do_eval(line, &mut context); let result = do_eval(line, &mut context);

18
src/util.rs Normal file
View file

@ -0,0 +1,18 @@
use evalexpr::{
Value,
EvalexprError
};
pub(crate) fn parse_radix(prefix: &str, base: u32, arg: &Value) -> Result<Value, EvalexprError> {
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());
}