Start work on serde

This commit is contained in:
Austen Adler 2021-05-03 20:03:56 -04:00
parent 4601b5104f
commit 13d4464ea2
6 changed files with 219 additions and 47 deletions

159
Cargo.lock generated
View File

@ -12,6 +12,61 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "confy"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2913470204e9e8498a0f31f17f90a0de801ae92c8c5ac18c49af4819e6786697"
dependencies = [
"directories",
"serde",
"toml",
]
[[package]]
name = "directories"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c"
dependencies = [
"cfg-if 0.1.10",
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "getrandom"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.93" version = "0.2.93"
@ -24,6 +79,24 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
[[package]]
name = "proc-macro2"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.6" version = "0.2.6"
@ -42,14 +115,57 @@ dependencies = [
"redox_syscall", "redox_syscall",
] ]
[[package]]
name = "redox_users"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom",
"redox_syscall",
]
[[package]] [[package]]
name = "rpn_rs" name = "rpn_rs"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"confy",
"serde",
"termion", "termion",
"tui", "tui",
] ]
[[package]]
name = "serde"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]] [[package]]
name = "termion" name = "termion"
version = "1.5.6" version = "1.5.6"
@ -62,6 +178,15 @@ dependencies = [
"redox_termios", "redox_termios",
] ]
[[package]]
name = "toml"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "tui" name = "tui"
version = "0.14.0" version = "0.14.0"
@ -86,3 +211,37 @@ name = "unicode-width"
version = "0.1.8" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -9,3 +9,5 @@ edition = "2018"
[dependencies] [dependencies]
tui = "0.14" tui = "0.14"
termion = "1.5" termion = "1.5"
serde = {version = "1.0", features = ["derive"]}
confy = "0.4.0"

View File

@ -9,9 +9,10 @@ use constants::{
}; };
use errors::{CalculatorError, CalculatorResult}; use errors::{CalculatorError, CalculatorResult};
use operations::{CalculatorOperation, CalculatorStateChange, MacroState, OpArgs}; use operations::{CalculatorOperation, CalculatorStateChange, MacroState, OpArgs};
use serde::{Deserialize, Serialize};
use std::collections::{HashSet, VecDeque}; use std::collections::{HashSet, VecDeque};
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug, Serialize, Deserialize)]
enum HistoryMode { enum HistoryMode {
One, One,
Macro, Macro,
@ -23,12 +24,13 @@ impl CalculatorStateChange {
} }
} }
pub struct Calculator<'a> { #[derive(Serialize, Deserialize)]
pub struct Calculator {
l: String, l: String,
stack: VecDeque<f64>, stack: VecDeque<f64>,
macros: CalculatorMacros<'a>, macros: CalculatorMacros,
active_macros: HashSet<char>, active_macros: HashSet<char>,
constants: CalculatorConstants<'a>, constants: CalculatorConstants,
registers: CalculatorRegisters, registers: CalculatorRegisters,
undo_buf: Vec<CalculatorStateChange>, undo_buf: Vec<CalculatorStateChange>,
redo_buf: Vec<CalculatorStateChange>, redo_buf: Vec<CalculatorStateChange>,
@ -37,8 +39,8 @@ pub struct Calculator<'a> {
display_mode: CalculatorDisplayMode, display_mode: CalculatorDisplayMode,
} }
impl<'a> Default for Calculator<'a> { impl Default for Calculator {
fn default() -> Calculator<'a> { fn default() -> Calculator {
Calculator { Calculator {
l: String::new(), l: String::new(),
stack: vec![1000.0, 1200.32].into_iter().collect(), stack: vec![1000.0, 1200.32].into_iter().collect(),
@ -51,50 +53,52 @@ impl<'a> Default for Calculator<'a> {
( (
'e', 'e',
CalculatorMacro { CalculatorMacro {
help: "Empty", help: String::from("Empty"),
value: "", value: String::from(""),
}, },
), ),
( (
'1', '1',
CalculatorMacro { CalculatorMacro {
help: "Push 1", help: String::from("Push 1"),
value: "1 ", value: String::from("1 "),
}, },
), ),
( (
'0', '0',
CalculatorMacro { CalculatorMacro {
help: "Push 0", help: String::from("Push 0"),
value: "0 ", value: String::from("0 "),
}, },
), ),
( (
't', 't',
CalculatorMacro { CalculatorMacro {
help: "Test", help: String::from("Test"),
value: "m1m0\\m1m1\\\\", value: String::from("m1m0\\m1m1\\\\"),
}, },
), ),
( (
'm', 'm',
CalculatorMacro { CalculatorMacro {
help: "<cr>64?>64%", help: String::from("<cr>64?>64%"),
value: " 64?>64%", value: String::from(" 64?>64%"),
}, },
), ),
( (
'u', 'u',
CalculatorMacro { CalculatorMacro {
help: "Quadratic Formula", help: String::from("Quadratic Formula"),
value: "RcRbRarbnrb2 ^4 rarc**-v+2 ra*/rbnrb2^4 rarc**-v-2 ra*/", value: String::from(
"RcRbRarbnrb2 ^4 rarc**-v+2 ra*/rbnrb2^4 rarc**-v-2 ra*/",
),
}, },
), ),
( (
's', 's',
CalculatorMacro { CalculatorMacro {
help: "Sample data", help: String::from("Sample data"),
value: "\\\\2 5 3n", value: String::from("\\\\2 5 3n"),
}, },
), ),
] ]
@ -105,21 +109,21 @@ impl<'a> Default for Calculator<'a> {
( (
't', 't',
CalculatorConstant { CalculatorConstant {
help: "Tau (2pi)", help: String::from("Tau (2pi)"),
value: std::f64::consts::TAU, value: std::f64::consts::TAU,
}, },
), ),
( (
'e', 'e',
CalculatorConstant { CalculatorConstant {
help: "Euler's Number e", help: String::from("Euler's Number e"),
value: std::f64::consts::E, value: std::f64::consts::E,
}, },
), ),
( (
'p', 'p',
CalculatorConstant { CalculatorConstant {
help: "Pi", help: String::from("Pi"),
value: std::f64::consts::PI, value: std::f64::consts::PI,
}, },
), ),
@ -133,7 +137,7 @@ impl<'a> Default for Calculator<'a> {
} }
} }
impl<'a> Calculator<'a> { impl Calculator {
pub fn take_input(&mut self, c: char) -> CalculatorResult<()> { pub fn take_input(&mut self, c: char) -> CalculatorResult<()> {
//for c in input.chars() { //for c in input.chars() {
match &self.state { match &self.state {
@ -201,8 +205,9 @@ impl<'a> Calculator<'a> {
Ok(()) Ok(())
} }
CalculatorState::WaitingForMacro => { CalculatorState::WaitingForMacro => {
let mac = *self.macros.get(&c).ok_or(CalculatorError::NoSuchMacro(c))?; let mac = self.macros.get(&c).ok_or(CalculatorError::NoSuchMacro(c))?;
let value = mac.value; // self.take_input below takes a mutable reference to self, so must clone the value here
let value = mac.value.clone();
if self.active_macros.contains(&c) { if self.active_macros.contains(&c) {
return Err(CalculatorError::RecursiveMacro(c)); return Err(CalculatorError::RecursiveMacro(c));
@ -343,10 +348,10 @@ impl<'a> Calculator<'a> {
pub fn get_state(&self) -> &CalculatorState { pub fn get_state(&self) -> &CalculatorState {
&self.state &self.state
} }
pub fn get_constants_iter(&'a self) -> CalculatorConstantsIter<'a> { pub fn get_constants_iter(&self) -> CalculatorConstantsIter {
self.constants.iter() self.constants.iter()
} }
pub fn get_macros_iter(&'a self) -> CalculatorMacrosIter<'a> { pub fn get_macros_iter(&self) -> CalculatorMacrosIter {
self.macros.iter() self.macros.iter()
} }
pub fn get_registers_iter(&self) -> CalculatorRegistersIter { pub fn get_registers_iter(&self) -> CalculatorRegistersIter {

View File

@ -1,11 +1,14 @@
use serde::{Deserialize, Serialize};
use std::collections::hash_map::Iter; use std::collections::hash_map::Iter;
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Serialize, Deserialize)]
pub enum RegisterState { pub enum RegisterState {
Save, Save,
Load, Load,
} }
#[derive(Serialize, Deserialize)]
pub enum CalculatorState { pub enum CalculatorState {
Normal, Normal,
WaitingForConstant, WaitingForConstant,
@ -14,33 +17,35 @@ pub enum CalculatorState {
WaitingForSetting, WaitingForSetting,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CalculatorConstant<'a> { pub struct CalculatorConstant {
pub help: &'a str, pub help: String,
pub value: f64, pub value: f64,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CalculatorMacro<'a> { pub struct CalculatorMacro {
pub help: &'a str, pub help: String,
pub value: &'a str, pub value: String,
} }
pub type CalculatorConstants<'a> = HashMap<char, CalculatorConstant<'a>>; pub type CalculatorConstants = HashMap<char, CalculatorConstant>;
pub type CalculatorConstantsIter<'a> = Iter<'a, char, CalculatorConstant<'a>>; pub type CalculatorConstantsIter<'a> = Iter<'a, char, CalculatorConstant>;
pub type CalculatorMacros<'a> = HashMap<char, CalculatorMacro<'a>>; pub type CalculatorMacros = HashMap<char, CalculatorMacro>;
pub type CalculatorMacrosIter<'a> = Iter<'a, char, CalculatorMacro<'a>>; pub type CalculatorMacrosIter<'a> = Iter<'a, char, CalculatorMacro>;
pub type CalculatorRegisters = HashMap<char, f64>; pub type CalculatorRegisters = HashMap<char, f64>;
pub type CalculatorRegistersIter<'a> = Iter<'a, char, f64>; pub type CalculatorRegistersIter<'a> = Iter<'a, char, f64>;
#[derive(Serialize, Deserialize)]
pub enum CalculatorAngleMode { pub enum CalculatorAngleMode {
Degrees, Degrees,
Radians, Radians,
Grads, Grads,
} }
#[derive(Serialize, Deserialize)]
pub enum CalculatorDisplayMode { pub enum CalculatorDisplayMode {
Default(Option<char>), Default(Option<char>),
Scientific(usize), Scientific(usize),

View File

@ -1,10 +1,11 @@
#[derive(PartialEq, Debug)] use serde::{Deserialize, Serialize};
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum MacroState { pub enum MacroState {
Start, Start,
End, End,
} }
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum CalculatorOperation { pub enum CalculatorOperation {
Add, Add,
Subtract, Subtract,
@ -36,7 +37,7 @@ pub enum CalculatorOperation {
Macro(MacroState), Macro(MacroState),
} }
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum OpArgs { pub enum OpArgs {
Macro(MacroState), Macro(MacroState),
Unary(f64), Unary(f64),
@ -44,7 +45,7 @@ pub enum OpArgs {
None, None,
} }
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct CalculatorStateChange { pub struct CalculatorStateChange {
pub pop: OpArgs, pub pop: OpArgs,
pub push: OpArgs, pub push: OpArgs,

View File

@ -32,15 +32,15 @@ enum AppState {
Help, Help,
} }
struct App<'a> { struct App {
calculator: Calculator<'a>, calculator: Calculator,
error_msg: Option<String>, error_msg: Option<String>,
state: AppState, state: AppState,
current_macro: Option<char>, current_macro: Option<char>,
} }
impl<'a> Default for App<'a> { impl Default for App {
fn default() -> App<'a> { fn default() -> App {
App { App {
calculator: Calculator::default(), calculator: Calculator::default(),
error_msg: None, error_msg: None,