Start serializing
This commit is contained in:
parent
13d4464ea2
commit
11fcae4db3
206
src/calc.rs
206
src/calc.rs
@ -2,16 +2,21 @@ pub mod constants;
|
|||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod operations;
|
pub mod operations;
|
||||||
|
|
||||||
|
use confy::{load, store};
|
||||||
use constants::{
|
use constants::{
|
||||||
CalculatorAngleMode, CalculatorConstant, CalculatorConstants, CalculatorConstantsIter,
|
CalculatorAngleMode, CalculatorConstants, CalculatorConstantsIter, CalculatorDisplayMode,
|
||||||
CalculatorDisplayMode, CalculatorMacro, CalculatorMacros, CalculatorMacrosIter,
|
CalculatorMacros, CalculatorMacrosIter, CalculatorRegisters, CalculatorRegistersIter,
|
||||||
CalculatorRegisters, CalculatorRegistersIter, CalculatorState, RegisterState,
|
CalculatorSettings, CalculatorState, RegisterState,
|
||||||
};
|
};
|
||||||
use errors::{CalculatorError, CalculatorResult};
|
use errors::{CalculatorError, CalculatorResult};
|
||||||
use operations::{CalculatorOperation, CalculatorStateChange, MacroState, OpArgs};
|
use operations::{CalculatorOperation, CalculatorStateChange, MacroState, OpArgs};
|
||||||
|
use serde::ser::{SerializeStruct, Serializer};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::collections::{HashSet, VecDeque};
|
use std::collections::{HashSet, VecDeque};
|
||||||
|
|
||||||
|
const APP_NAME: &str = "rpn_rs";
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Serialize, Deserialize)]
|
#[derive(PartialEq, Debug, Serialize, Deserialize)]
|
||||||
enum HistoryMode {
|
enum HistoryMode {
|
||||||
One,
|
One,
|
||||||
@ -24,122 +29,133 @@ impl CalculatorStateChange {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct Calculator {
|
pub struct Calculator {
|
||||||
|
#[serde(skip)]
|
||||||
l: String,
|
l: String,
|
||||||
stack: VecDeque<f64>,
|
stack: VecDeque<f64>,
|
||||||
|
#[serde(serialize_with = "ordered_char_map")]
|
||||||
macros: CalculatorMacros,
|
macros: CalculatorMacros,
|
||||||
|
#[serde(skip)]
|
||||||
active_macros: HashSet<char>,
|
active_macros: HashSet<char>,
|
||||||
constants: CalculatorConstants,
|
constants: CalculatorConstants,
|
||||||
registers: CalculatorRegisters,
|
registers: CalculatorRegisters,
|
||||||
|
#[serde(skip)]
|
||||||
undo_buf: Vec<CalculatorStateChange>,
|
undo_buf: Vec<CalculatorStateChange>,
|
||||||
|
#[serde(skip)]
|
||||||
redo_buf: Vec<CalculatorStateChange>,
|
redo_buf: Vec<CalculatorStateChange>,
|
||||||
|
#[serde(skip)]
|
||||||
state: CalculatorState,
|
state: CalculatorState,
|
||||||
|
// TODO:
|
||||||
|
#[serde(skip)]
|
||||||
angle_mode: CalculatorAngleMode,
|
angle_mode: CalculatorAngleMode,
|
||||||
|
// TODO:
|
||||||
|
#[serde(skip)]
|
||||||
display_mode: CalculatorDisplayMode,
|
display_mode: CalculatorDisplayMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ordered_char_map<S, T>(value: &HashMap<char, T>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
T: Serialize,
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
// let ordered: HashMap<_, _> = value
|
||||||
|
// .iter()
|
||||||
|
// .map(|(key, t)| (String::from(*key), t.clone()))
|
||||||
|
// .collect();
|
||||||
|
let ordered: BTreeMap<_, _> = value
|
||||||
|
.iter()
|
||||||
|
.map(|(key, t)| (String::from(*key), t.clone()))
|
||||||
|
.collect();
|
||||||
|
ordered.serialize(serializer)
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Calculator {
|
impl Default for Calculator {
|
||||||
fn default() -> Calculator {
|
fn default() -> Self {
|
||||||
Calculator {
|
Calculator::with_settings(CalculatorSettings::default())
|
||||||
|
.expect("Default calculator config is corrupt! Cannot start.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for Calculator {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let mut s = serializer.serialize_struct("Calculator", 2)?;
|
||||||
|
s.serialize_field("l", &self.l)?;
|
||||||
|
s.serialize_field("state", &self.state)?;
|
||||||
|
// s.serialize_field("k", &self.registers)?; // map key was not a string
|
||||||
|
//s.serialize_field("t", &self.undo_buf)?; // unsupported Rust type
|
||||||
|
s.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Calculator {
|
||||||
|
pub fn with_settings(settings: CalculatorSettings) -> CalculatorResult<Calculator> {
|
||||||
|
let angle_mode = settings.angle_mode;
|
||||||
|
let display_mode = settings.display_mode;
|
||||||
|
Ok(Calculator {
|
||||||
l: String::new(),
|
l: String::new(),
|
||||||
stack: vec![1000.0, 1200.32].into_iter().collect(),
|
|
||||||
state: CalculatorState::Normal,
|
state: CalculatorState::Normal,
|
||||||
undo_buf: vec![],
|
undo_buf: vec![],
|
||||||
redo_buf: vec![],
|
redo_buf: vec![],
|
||||||
active_macros: HashSet::new(),
|
active_macros: HashSet::new(),
|
||||||
registers: CalculatorRegisters::new(),
|
registers: CalculatorRegisters::new(),
|
||||||
macros: [
|
stack: settings.stack.into(),
|
||||||
(
|
macros: settings
|
||||||
'e',
|
.macros
|
||||||
CalculatorMacro {
|
.into_iter()
|
||||||
help: String::from("Empty"),
|
.map(|(key, mac)| {
|
||||||
value: String::from(""),
|
Ok((
|
||||||
},
|
key.chars()
|
||||||
),
|
.next()
|
||||||
(
|
.ok_or_else(|| CalculatorError::LoadError(None))?,
|
||||||
'1',
|
mac,
|
||||||
CalculatorMacro {
|
))
|
||||||
help: String::from("Push 1"),
|
})
|
||||||
value: String::from("1 "),
|
.collect::<CalculatorResult<CalculatorMacros>>()?,
|
||||||
},
|
constants: settings
|
||||||
),
|
.constants
|
||||||
(
|
.into_iter()
|
||||||
'0',
|
.map(|(key, constant)| {
|
||||||
CalculatorMacro {
|
Ok((
|
||||||
help: String::from("Push 0"),
|
key.chars()
|
||||||
value: String::from("0 "),
|
.next()
|
||||||
},
|
.ok_or_else(|| CalculatorError::LoadError(None))?,
|
||||||
),
|
constant,
|
||||||
(
|
))
|
||||||
't',
|
})
|
||||||
CalculatorMacro {
|
.collect::<CalculatorResult<CalculatorConstants>>()?,
|
||||||
help: String::from("Test"),
|
angle_mode,
|
||||||
value: String::from("m1m0\\m1m1\\\\"),
|
display_mode,
|
||||||
},
|
})
|
||||||
),
|
}
|
||||||
(
|
|
||||||
'm',
|
pub fn load_config() -> CalculatorResult<Calculator> {
|
||||||
CalculatorMacro {
|
let settings = load(APP_NAME).map_err(|e| CalculatorError::LoadError(Some(e)))?;
|
||||||
help: String::from("<cr>64?>64%"),
|
Calculator::with_settings(settings)
|
||||||
value: String::from(" 64?>64%"),
|
}
|
||||||
},
|
pub fn save_config(&self) -> CalculatorResult<()> {
|
||||||
),
|
let settings = CalculatorSettings {
|
||||||
(
|
angle_mode: self.angle_mode.clone(),
|
||||||
'u',
|
display_mode: self.display_mode.clone(),
|
||||||
CalculatorMacro {
|
stack: self.stack.iter().map(|f| *f).collect(),
|
||||||
help: String::from("Quadratic Formula"),
|
macros: self
|
||||||
value: String::from(
|
.macros
|
||||||
"RcRbRarbnrb2 ^4 rarc**-v+2 ra*/rbnrb2^4 rarc**-v-2 ra*/",
|
.iter()
|
||||||
),
|
.map(|(key, mac)| (String::from(*key), mac.clone()))
|
||||||
},
|
.collect(),
|
||||||
),
|
constants: self
|
||||||
(
|
.constants
|
||||||
's',
|
.iter()
|
||||||
CalculatorMacro {
|
.map(|(key, constant)| (String::from(*key), constant.clone()))
|
||||||
help: String::from("Sample data"),
|
.collect(),
|
||||||
value: String::from("\\\\2 5 3n"),
|
};
|
||||||
},
|
store(APP_NAME, settings).map_err(|e| CalculatorError::SaveError(Some(e)))
|
||||||
),
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.collect(),
|
|
||||||
constants: [
|
|
||||||
(
|
|
||||||
't',
|
|
||||||
CalculatorConstant {
|
|
||||||
help: String::from("Tau (2pi)"),
|
|
||||||
value: std::f64::consts::TAU,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
'e',
|
|
||||||
CalculatorConstant {
|
|
||||||
help: String::from("Euler's Number e"),
|
|
||||||
value: std::f64::consts::E,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
'p',
|
|
||||||
CalculatorConstant {
|
|
||||||
help: String::from("Pi"),
|
|
||||||
value: std::f64::consts::PI,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.collect(),
|
|
||||||
angle_mode: CalculatorAngleMode::Degrees,
|
|
||||||
display_mode: CalculatorDisplayMode::Default(None),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
|
||||||
match &self.state {
|
match &self.state {
|
||||||
CalculatorState::Normal => match c {
|
CalculatorState::Normal => match c {
|
||||||
c @ '0'..='9' | c @ '.' | c @ 'e' => self.entry(c),
|
c @ '0'..='9' | c @ '.' | c @ 'e' => self.entry(c),
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::hash_map::Iter;
|
use std::collections::hash_map::Iter;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum RegisterState {
|
pub enum RegisterState {
|
||||||
Save,
|
Save,
|
||||||
Load,
|
Load,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum CalculatorState {
|
pub enum CalculatorState {
|
||||||
Normal,
|
Normal,
|
||||||
WaitingForConstant,
|
WaitingForConstant,
|
||||||
@ -17,13 +18,21 @@ pub enum CalculatorState {
|
|||||||
WaitingForSetting,
|
WaitingForSetting,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for CalculatorState {
|
||||||
|
fn default() -> Self {
|
||||||
|
CalculatorState::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "constant")]
|
||||||
pub struct CalculatorConstant {
|
pub struct CalculatorConstant {
|
||||||
pub help: String,
|
pub help: String,
|
||||||
pub value: f64,
|
pub value: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "macro")]
|
||||||
pub struct CalculatorMacro {
|
pub struct CalculatorMacro {
|
||||||
pub help: String,
|
pub help: String,
|
||||||
pub value: String,
|
pub value: String,
|
||||||
@ -38,16 +47,154 @@ 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)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "angle_mode")]
|
||||||
pub enum CalculatorAngleMode {
|
pub enum CalculatorAngleMode {
|
||||||
Degrees,
|
Degrees,
|
||||||
Radians,
|
Radians,
|
||||||
Grads,
|
Grads,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
impl fmt::Display for CalculatorAngleMode {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
CalculatorAngleMode::Degrees => write!(f, "DEG"),
|
||||||
|
CalculatorAngleMode::Radians => write!(f, "RAD"),
|
||||||
|
CalculatorAngleMode::Grads => write!(f, "GRD"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CalculatorAngleMode {
|
||||||
|
fn default() -> Self {
|
||||||
|
CalculatorAngleMode::Degrees
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "display_mode")]
|
||||||
pub enum CalculatorDisplayMode {
|
pub enum CalculatorDisplayMode {
|
||||||
Default(Option<char>),
|
Default(Option<char>),
|
||||||
Scientific(usize),
|
Scientific(usize),
|
||||||
Engineering(usize),
|
Engineering(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for CalculatorDisplayMode {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
CalculatorDisplayMode::Default(None) => write!(f, "DEF"),
|
||||||
|
CalculatorDisplayMode::Default(Some(c)) => write!(f, "DEF({})", c),
|
||||||
|
CalculatorDisplayMode::Scientific(p) => write!(f, "SCI({})", p),
|
||||||
|
CalculatorDisplayMode::Engineering(p) => write!(f, "ENG({})", p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CalculatorDisplayMode {
|
||||||
|
fn default() -> Self {
|
||||||
|
CalculatorDisplayMode::Default(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct CalculatorSettings {
|
||||||
|
// Order matters here as macros/constants cannot come first
|
||||||
|
pub stack: Vec<f64>,
|
||||||
|
#[serde(skip)]
|
||||||
|
pub display_mode: CalculatorDisplayMode,
|
||||||
|
pub angle_mode: CalculatorAngleMode,
|
||||||
|
pub macros: HashMap<String, CalculatorMacro>,
|
||||||
|
pub constants: HashMap<String, CalculatorConstant>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CalculatorSettings {
|
||||||
|
fn default() -> CalculatorSettings {
|
||||||
|
CalculatorSettings {
|
||||||
|
stack: vec![1.0, 2.0].into_iter().collect(),
|
||||||
|
macros: [
|
||||||
|
(
|
||||||
|
String::from('e'),
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("Empty"),
|
||||||
|
value: String::from(""),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
String::from('1'),
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("Push 1"),
|
||||||
|
value: String::from("1 "),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
String::from('0'),
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("Push 0"),
|
||||||
|
value: String::from("0 "),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
String::from('t'),
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("Test"),
|
||||||
|
value: String::from("m1m0\\m1m1\\\\"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
String::from('m'),
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("<cr>64?>64%"),
|
||||||
|
value: String::from(" 64?>64%"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
String::from('u'),
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("Quadratic Formula"),
|
||||||
|
value: String::from(
|
||||||
|
"RcRbRarbnrb2 ^4 rarc**-v+2 ra*/rbnrb2^4 rarc**-v-2 ra*/",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
String::from('s'),
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("Sample data"),
|
||||||
|
value: String::from("\\\\2 5 3n"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
|
constants: [
|
||||||
|
(
|
||||||
|
String::from('t'),
|
||||||
|
CalculatorConstant {
|
||||||
|
help: String::from("Tau (2pi)"),
|
||||||
|
value: std::f64::consts::TAU,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
String::from('e'),
|
||||||
|
CalculatorConstant {
|
||||||
|
help: String::from("Euler's Number e"),
|
||||||
|
value: std::f64::consts::E,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
String::from('p'),
|
||||||
|
CalculatorConstant {
|
||||||
|
help: String::from("Pi"),
|
||||||
|
value: std::f64::consts::PI,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
|
angle_mode: CalculatorAngleMode::Degrees,
|
||||||
|
display_mode: CalculatorDisplayMode::Default(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
use confy::ConfyError;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
pub type CalculatorResult<T> = Result<T, CalculatorError>;
|
pub type CalculatorResult<T> = Result<T, CalculatorError>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum CalculatorError {
|
pub enum CalculatorError {
|
||||||
ArithmeticError,
|
ArithmeticError,
|
||||||
NotEnoughStackEntries,
|
NotEnoughStackEntries,
|
||||||
@ -15,6 +17,8 @@ pub enum CalculatorError {
|
|||||||
RecursiveMacro(char),
|
RecursiveMacro(char),
|
||||||
ParseError,
|
ParseError,
|
||||||
PrecisionTooHigh,
|
PrecisionTooHigh,
|
||||||
|
SaveError(Option<ConfyError>),
|
||||||
|
LoadError(Option<ConfyError>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CalculatorError {
|
impl fmt::Display for CalculatorError {
|
||||||
@ -34,6 +38,10 @@ impl fmt::Display for CalculatorError {
|
|||||||
CalculatorError::RecursiveMacro(c) => write!(f, "Recursive macro '{}'", c),
|
CalculatorError::RecursiveMacro(c) => write!(f, "Recursive macro '{}'", c),
|
||||||
CalculatorError::ParseError => write!(f, "Parse error"),
|
CalculatorError::ParseError => write!(f, "Parse error"),
|
||||||
CalculatorError::PrecisionTooHigh => write!(f, "Precision too high"),
|
CalculatorError::PrecisionTooHigh => write!(f, "Precision too high"),
|
||||||
|
CalculatorError::SaveError(None) => write!(f, "Could not save"),
|
||||||
|
CalculatorError::SaveError(Some(e)) => write!(f, "Could not save: {}", e),
|
||||||
|
CalculatorError::LoadError(None) => write!(f, "Could not load"),
|
||||||
|
CalculatorError::LoadError(Some(e)) => write!(f, "Could not load: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
src/main.rs
33
src/main.rs
@ -4,7 +4,7 @@
|
|||||||
mod calc;
|
mod calc;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use calc::constants::{CalculatorAngleMode, CalculatorDisplayMode, CalculatorState, RegisterState};
|
use calc::constants::{CalculatorDisplayMode, CalculatorState, RegisterState};
|
||||||
use calc::errors::CalculatorResult;
|
use calc::errors::CalculatorResult;
|
||||||
use calc::Calculator;
|
use calc::Calculator;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
@ -41,9 +41,13 @@ struct App {
|
|||||||
|
|
||||||
impl Default for App {
|
impl Default for App {
|
||||||
fn default() -> App {
|
fn default() -> App {
|
||||||
|
let (calculator, error_msg) = match Calculator::load_config() {
|
||||||
|
Ok(c) => (c, None),
|
||||||
|
Err(e) => (Calculator::default(), Some(format!("{}", e))),
|
||||||
|
};
|
||||||
App {
|
App {
|
||||||
calculator: Calculator::default(),
|
calculator,
|
||||||
error_msg: None,
|
error_msg,
|
||||||
state: AppState::Calculator,
|
state: AppState::Calculator,
|
||||||
current_macro: None,
|
current_macro: None,
|
||||||
}
|
}
|
||||||
@ -81,20 +85,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
Span::styled(e, Style::default().add_modifier(Modifier::RAPID_BLINK)),
|
Span::styled(e, Style::default().add_modifier(Modifier::RAPID_BLINK)),
|
||||||
],
|
],
|
||||||
(None, AppState::Calculator) => {
|
(None, AppState::Calculator) => {
|
||||||
// TODO: There has to be a better way than making strings each time
|
|
||||||
let display_mode_str = match app.calculator.get_display_mode() {
|
|
||||||
CalculatorDisplayMode::Default(None) => String::from("DEF"),
|
|
||||||
CalculatorDisplayMode::Default(Some(c)) => format!("DEF({})", c),
|
|
||||||
CalculatorDisplayMode::Scientific(p) => format!("SCI({})", p),
|
|
||||||
CalculatorDisplayMode::Engineering(p) => format!("ENG({})", p),
|
|
||||||
};
|
|
||||||
|
|
||||||
let angle_mode_str = match app.calculator.get_angle_mode() {
|
|
||||||
CalculatorAngleMode::Degrees => String::from("DEG"),
|
|
||||||
CalculatorAngleMode::Radians => String::from("RAD"),
|
|
||||||
CalculatorAngleMode::Grads => String::from("GRD"),
|
|
||||||
};
|
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
Span::raw("Press "),
|
Span::raw("Press "),
|
||||||
Span::styled("q", Style::default().add_modifier(Modifier::BOLD)),
|
Span::styled("q", Style::default().add_modifier(Modifier::BOLD)),
|
||||||
@ -102,7 +92,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
Span::styled("h", Style::default().add_modifier(Modifier::BOLD)),
|
Span::styled("h", Style::default().add_modifier(Modifier::BOLD)),
|
||||||
Span::raw(format!(
|
Span::raw(format!(
|
||||||
" for help - [{}] [{}]",
|
" for help - [{}] [{}]",
|
||||||
display_mode_str, angle_mode_str
|
app.calculator.get_display_mode(),
|
||||||
|
app.calculator.get_angle_mode()
|
||||||
)),
|
)),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -293,6 +284,12 @@ fn handle_key(app: &mut App, events: &Events, key: Key) -> CalculatorResult<bool
|
|||||||
Key::Char('q') => {
|
Key::Char('q') => {
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
Key::Ctrl('s') => {
|
||||||
|
app.calculator.save_config()?;
|
||||||
|
}
|
||||||
|
Key::Ctrl('l') => {
|
||||||
|
app.calculator = Calculator::load_config()?;
|
||||||
|
}
|
||||||
Key::Char('h') => {
|
Key::Char('h') => {
|
||||||
app.state = AppState::Help;
|
app.state = AppState::Help;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user