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

View File

@ -17,6 +17,7 @@ tui = { version = "0.14", default-features = false, features = ['crossterm'] }
serde = {version = "1.0", features = ["derive"]} serde = {version = "1.0", features = ["derive"]}
# confy = "0.4.0" # confy = "0.4.0"
toml = "0.4.2" toml = "0.4.2"
lazy_static = "1.4.0"
[dependencies.confy] [dependencies.confy]
# TODO: Update this to v0.5.0 when it finally comes out -- for now, use latest git master # 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; pub mod entries;
use lazy_static::lazy_static;
pub mod errors; pub mod errors;
pub mod operations; pub mod operations;
pub mod types; pub mod types;
@ -27,6 +28,79 @@ const APP_NAME: &str = "rpn_rs";
/// The default precision to sue /// The default precision to sue
const DEFAULT_PRECISION: usize = 3; 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 /// The history mode of the entry - either a single change or a macro bound
#[derive(PartialEq, Debug, Serialize, Deserialize)] #[derive(PartialEq, Debug, Serialize, Deserialize)]
enum HistoryMode { enum HistoryMode {
@ -115,13 +189,6 @@ impl Default for Calculator {
value: String::from("RcRbRarbnrb2^4rarc**-v+2ra*/rbnrb2^4rarc**-v-2ra*/"), value: String::from("RcRbRarbnrb2^4rarc**-v+2ra*/rbnrb2^4rarc**-v-2ra*/"),
}, },
), ),
(
't',
CalculatorMacro {
help: String::from("Testing"),
value: String::from("1 V1 "),
},
),
] ]
.iter() .iter()
.cloned() .cloned()
@ -219,74 +286,6 @@ impl Calculator {
} }
_ => Err(CalculatorError::ParseError), _ => 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 // State modifiers
'm' => { 'm' => {
self.state = CalculatorState::WaitingForMacro; self.state = CalculatorState::WaitingForMacro;
@ -308,7 +307,7 @@ impl Calculator {
self.state = CalculatorState::WaitingForSetting; self.state = CalculatorState::WaitingForSetting;
Ok(()) 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<()> { fn constant_input(&mut self, c: char) -> CalculatorResult<()> {
@ -333,7 +332,7 @@ impl Calculator {
} }
// Record the macro started, if this is the outer macro // 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 // Record that we are running macro c
self.active_macros.insert(c); self.active_macros.insert(c);
@ -352,7 +351,7 @@ impl Calculator {
self.active_macros.remove(&c); self.active_macros.remove(&c);
// Record the macro is over, if this is the outer macro // Record the macro is over, if this is the outer macro
self.op(CalculatorOperation::Macro(MacroState::End))?; self.op(&CalculatorOperation::Macro(MacroState::End))?;
Ok(()) Ok(())
} }
@ -432,7 +431,7 @@ impl Calculator {
if !self.active_macros.is_empty() { if !self.active_macros.is_empty() {
self.active_macros.clear(); self.active_macros.clear();
// Should always be successful, but report the error if there is one // 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(()) Ok(())
} }
@ -604,7 +603,7 @@ impl Calculator {
} }
/// Performs a calculator operation such as undo, redo, operator, or dup /// 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 // Dup is special -- don't actually run it if l needs to be flushed
if self.flush_l()? { if self.flush_l()? {
if let CalculatorOperation::Dup = op { if let CalculatorOperation::Dup = op {
@ -693,7 +692,7 @@ impl Calculator {
Ok(CalculatorStateChange { Ok(CalculatorStateChange {
pop: OpArgs::None, pop: OpArgs::None,
push: OpArgs::Macro(state), push: OpArgs::Macro(*state),
}) })
} }
}; };

View File

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