49 lines
1.1 KiB
Rust
49 lines
1.1 KiB
Rust
use std::num::ParseIntError;
|
|
|
|
#[allow(dead_code)]
|
|
pub enum EvalError {
|
|
LeftMissing,
|
|
RightMissing,
|
|
I64Conversion(ParseIntError),
|
|
InvalidOperator(String)
|
|
}
|
|
|
|
pub struct Input {
|
|
pub left: i64,
|
|
pub right: i64
|
|
}
|
|
|
|
pub struct EvalResult {
|
|
pub input: Input,
|
|
pub eval: i64
|
|
}
|
|
|
|
fn parse(arg: &str) -> Result<i64, EvalError> {
|
|
match arg {
|
|
"true" => Ok(1),
|
|
"false" => Ok(0),
|
|
arg => arg.parse::<i64>().map_or_else(|e| Err(EvalError::I64Conversion(e)), Ok)
|
|
}
|
|
}
|
|
|
|
pub fn eval(expression: Vec<&str>) -> Result<EvalResult, EvalError> {
|
|
// let left = expression.get(0);
|
|
let left = parse(expression[0])?;
|
|
let right = parse(expression[2])?;
|
|
let wrap_result = |val: i64| -> EvalResult {
|
|
EvalResult {
|
|
input: Input { left, right },
|
|
eval: val,
|
|
}
|
|
};
|
|
|
|
match expression[1] {
|
|
">>" | "right" => Ok(wrap_result(left >> right)),
|
|
"<<" | "left" => Ok(wrap_result(left << right)),
|
|
"|" | "or" => Ok(wrap_result(left | right)),
|
|
"&" | "and" => Ok(wrap_result(left & right)),
|
|
"^" | "xor" => Ok(wrap_result(left ^ right)),
|
|
str => Err(EvalError::InvalidOperator(str.to_owned()))
|
|
}
|
|
}
|