Use lazy_static for mapping operations

This commit is contained in:
Austen Adler 2021-10-02 08:44:45 -04:00
parent 8a03445936
commit 6b24456f87
4 changed files with 87 additions and 84 deletions

3
Cargo.lock generated
View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "1.2.1"
@ -235,6 +237,7 @@ version = "0.6.0"
dependencies = [
"confy",
"crossterm",
"lazy_static",
"serde",
"toml",
"tui",

View File

@ -17,6 +17,7 @@ tui = { version = "0.14", default-features = false, features = ['crossterm'] }
serde = {version = "1.0", features = ["derive"]}
# confy = "0.4.0"
toml = "0.4.2"
lazy_static = "1.4.0"
[dependencies.confy]
# TODO: Update this to v0.5.0 when it finally comes out -- for now, use latest git master

View File

@ -1,4 +1,5 @@
pub mod entries;
use lazy_static::lazy_static;
pub mod errors;
pub mod operations;
pub mod types;
@ -27,6 +28,79 @@ const APP_NAME: &str = "rpn_rs";
/// The default precision to sue
const DEFAULT_PRECISION: usize = 3;
lazy_static! {
static ref OPERATION_MAP: HashMap<char, CalculatorOperation> = [
('+', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Add),
),
('-', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Subtract),
),
('*', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Multiply),
),
('/', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Divide),
),
('n', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Negate),
),
('|', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::AbsoluteValue),
),
('i', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Inverse),
),
('%', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Modulo),
),
('?', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::IntegerDivide),
),
('s', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Sin),
),
('c', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Cos),
),
('t', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Tan),
),
('S', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::ASin),
),
('C', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::ACos),
),
('T', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::ATan),
),
('v', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Sqrt),
),
('^', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Pow),
),
('l', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Log),
),
('L', CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Ln),
),
// Temporary
('V', CalculatorOperation::BuildVector),
('M', CalculatorOperation::BuildMatrix),
('_', CalculatorOperation::Deconstruct),
(')', CalculatorOperation::Transpose),
// Special
('\\', CalculatorOperation::Drop),
(' ', CalculatorOperation::Dup),
('>', CalculatorOperation::Swap),
('u', CalculatorOperation::Undo),
('U', CalculatorOperation::Redo),
].iter().copied().collect();
}
/// The history mode of the entry - either a single change or a macro bound
#[derive(PartialEq, Debug, Serialize, Deserialize)]
enum HistoryMode {
@ -115,13 +189,6 @@ impl Default for Calculator {
value: String::from("RcRbRarbnrb2^4rarc**-v+2ra*/rbnrb2^4rarc**-v-2ra*/"),
},
),
(
't',
CalculatorMacro {
help: String::from("Testing"),
value: String::from("1 V1 "),
},
),
]
.iter()
.cloned()
@ -219,74 +286,6 @@ impl Calculator {
}
_ => Err(CalculatorError::ParseError),
},
'+' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Add,
)),
'-' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Subtract,
)),
'*' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Multiply,
)),
'/' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Divide,
)),
'n' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Negate,
)),
'|' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::AbsoluteValue,
)),
'i' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Inverse,
)),
'%' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Modulo,
)),
'?' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::IntegerDivide,
)),
's' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Sin,
)),
'c' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Cos,
)),
't' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Tan,
)),
'S' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::ASin,
)),
'C' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::ACos,
)),
'T' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::ATan,
)),
'v' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Sqrt,
)),
'^' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Pow,
)),
'l' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Log,
)),
'L' => self.op(CalculatorOperation::ArithmeticOperation(
ArithmeticOperation::Ln,
)),
// Temporary
'V' => self.op(CalculatorOperation::BuildVector),
'M' => self.op(CalculatorOperation::BuildMatrix),
'_' => self.op(CalculatorOperation::Deconstruct),
')' => self.op(CalculatorOperation::Transpose),
// Special
'\\' => self.op(CalculatorOperation::Drop),
' ' => self.op(CalculatorOperation::Dup),
'>' => self.op(CalculatorOperation::Swap),
'u' => self.op(CalculatorOperation::Undo),
'U' => self.op(CalculatorOperation::Redo),
// State modifiers
'm' => {
self.state = CalculatorState::WaitingForMacro;
@ -308,7 +307,7 @@ impl Calculator {
self.state = CalculatorState::WaitingForSetting;
Ok(())
}
_ => Err(CalculatorError::NoSuchOperator(c)),
c => self.op(OPERATION_MAP.get(&c).ok_or(CalculatorError::NoSuchOperator(c))?),
}
}
fn constant_input(&mut self, c: char) -> CalculatorResult<()> {
@ -333,7 +332,7 @@ impl Calculator {
}
// Record the macro started, if this is the outer macro
self.op(CalculatorOperation::Macro(MacroState::Start))?;
self.op(&CalculatorOperation::Macro(MacroState::Start))?;
// Record that we are running macro c
self.active_macros.insert(c);
@ -352,7 +351,7 @@ impl Calculator {
self.active_macros.remove(&c);
// Record the macro is over, if this is the outer macro
self.op(CalculatorOperation::Macro(MacroState::End))?;
self.op(&CalculatorOperation::Macro(MacroState::End))?;
Ok(())
}
@ -432,7 +431,7 @@ impl Calculator {
if !self.active_macros.is_empty() {
self.active_macros.clear();
// Should always be successful, but report the error if there is one
self.op(CalculatorOperation::Macro(MacroState::End))?;
self.op(&CalculatorOperation::Macro(MacroState::End))?;
}
Ok(())
}
@ -604,7 +603,7 @@ impl Calculator {
}
/// Performs a calculator operation such as undo, redo, operator, or dup
pub fn op(&mut self, op: CalculatorOperation) -> CalculatorResult<()> {
pub fn op(&mut self, op: &CalculatorOperation) -> CalculatorResult<()> {
// Dup is special -- don't actually run it if l needs to be flushed
if self.flush_l()? {
if let CalculatorOperation::Dup = op {
@ -693,7 +692,7 @@ impl Calculator {
Ok(CalculatorStateChange {
pop: OpArgs::None,
push: OpArgs::Macro(state),
push: OpArgs::Macro(*state),
})
}
};

View File

@ -1,7 +1,7 @@
use super::entries::Entry;
use serde::{Deserialize, Serialize};
#[derive(PartialEq, Debug, Serialize, Deserialize)]
#[derive(PartialEq, Debug, Serialize, Deserialize, Copy, Clone)]
pub enum ArithmeticOperation {
Add,
Subtract,
@ -24,7 +24,7 @@ pub enum ArithmeticOperation {
Ln,
}
/// Operations that can be sent to the calculator such as +, -, or undo
#[derive(PartialEq, Debug, Serialize, Deserialize)]
#[derive(PartialEq, Debug, Serialize, Deserialize, Copy, Clone)]
pub enum CalculatorOperation {
ArithmeticOperation(ArithmeticOperation),
BuildVector,
@ -40,7 +40,7 @@ pub enum CalculatorOperation {
}
/// Macro bundary; defined by the start or end of a macro invocation
#[derive(PartialEq, Debug, Serialize, Deserialize)]
#[derive(PartialEq, Debug, Serialize, Deserialize, Copy, Clone)]
pub enum MacroState {
Start,
End,