Add fixed
This commit is contained in:
parent
11fcae4db3
commit
61fa6ee530
182
src/calc.rs
182
src/calc.rs
@ -4,18 +4,19 @@ pub mod operations;
|
|||||||
|
|
||||||
use confy::{load, store};
|
use confy::{load, store};
|
||||||
use constants::{
|
use constants::{
|
||||||
CalculatorAngleMode, CalculatorConstants, CalculatorConstantsIter, CalculatorDisplayMode,
|
CalculatorAngleMode, CalculatorConstant, CalculatorConstants, CalculatorConstantsIter,
|
||||||
CalculatorMacros, CalculatorMacrosIter, CalculatorRegisters, CalculatorRegistersIter,
|
CalculatorDisplayMode, CalculatorMacro, CalculatorMacros, CalculatorMacrosIter,
|
||||||
CalculatorSettings, CalculatorState, RegisterState,
|
CalculatorRegisters, CalculatorRegistersIter, 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::ser::Serializer;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::collections::{HashSet, VecDeque};
|
use std::collections::{HashSet, VecDeque};
|
||||||
|
|
||||||
const APP_NAME: &str = "rpn_rs";
|
const APP_NAME: &str = "rpn_rs";
|
||||||
|
const DEFAULT_PRECISION: usize = 3;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Serialize, Deserialize)]
|
#[derive(PartialEq, Debug, Serialize, Deserialize)]
|
||||||
enum HistoryMode {
|
enum HistoryMode {
|
||||||
@ -29,7 +30,8 @@ impl CalculatorStateChange {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(default)]
|
||||||
pub struct Calculator {
|
pub struct Calculator {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
l: String,
|
l: String,
|
||||||
@ -38,7 +40,9 @@ pub struct Calculator {
|
|||||||
macros: CalculatorMacros,
|
macros: CalculatorMacros,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
active_macros: HashSet<char>,
|
active_macros: HashSet<char>,
|
||||||
|
#[serde(serialize_with = "ordered_char_map")]
|
||||||
constants: CalculatorConstants,
|
constants: CalculatorConstants,
|
||||||
|
#[serde(skip)]
|
||||||
registers: CalculatorRegisters,
|
registers: CalculatorRegisters,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
undo_buf: Vec<CalculatorStateChange>,
|
undo_buf: Vec<CalculatorStateChange>,
|
||||||
@ -46,12 +50,9 @@ pub struct Calculator {
|
|||||||
redo_buf: Vec<CalculatorStateChange>,
|
redo_buf: Vec<CalculatorStateChange>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
state: CalculatorState,
|
state: CalculatorState,
|
||||||
// TODO:
|
|
||||||
#[serde(skip)]
|
|
||||||
angle_mode: CalculatorAngleMode,
|
angle_mode: CalculatorAngleMode,
|
||||||
// TODO:
|
|
||||||
#[serde(skip)]
|
|
||||||
display_mode: CalculatorDisplayMode,
|
display_mode: CalculatorDisplayMode,
|
||||||
|
// calculator_alignment: CalculatorAlignment,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ordered_char_map<S, T>(value: &HashMap<char, T>, serializer: S) -> Result<S::Ok, S::Error>
|
fn ordered_char_map<S, T>(value: &HashMap<char, T>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
@ -59,10 +60,7 @@ where
|
|||||||
T: Serialize,
|
T: Serialize,
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
// let ordered: HashMap<_, _> = value
|
// Convert chars to string for TOML map; insert into BTreeMap to be sorted
|
||||||
// .iter()
|
|
||||||
// .map(|(key, t)| (String::from(*key), t.clone()))
|
|
||||||
// .collect();
|
|
||||||
let ordered: BTreeMap<_, _> = value
|
let ordered: BTreeMap<_, _> = value
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(key, t)| (String::from(*key), t.clone()))
|
.map(|(key, t)| (String::from(*key), t.clone()))
|
||||||
@ -72,94 +70,87 @@ where
|
|||||||
|
|
||||||
impl Default for Calculator {
|
impl Default for Calculator {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Calculator::with_settings(CalculatorSettings::default())
|
Calculator {
|
||||||
.expect("Default calculator config is corrupt! Cannot start.")
|
l: String::new(),
|
||||||
|
redo_buf: vec![],
|
||||||
|
undo_buf: vec![],
|
||||||
|
active_macros: HashSet::new(),
|
||||||
|
registers: CalculatorRegisters::new(),
|
||||||
|
state: CalculatorState::Normal,
|
||||||
|
stack: vec![1.0, 2.0].into_iter().collect(),
|
||||||
|
macros: [
|
||||||
|
(
|
||||||
|
'e',
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("Empty"),
|
||||||
|
value: String::from(""),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'm',
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("<cr>64?>64%"),
|
||||||
|
value: String::from(" 64?>64%"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'u',
|
||||||
|
CalculatorMacro {
|
||||||
|
help: String::from("Quadratic Formula"),
|
||||||
|
value: String::from(
|
||||||
|
"RcRbRarbnrb2 ^4 rarc**-v+2 ra*/rbnrb2^4 rarc**-v-2 ra*/",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
.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::default(),
|
||||||
|
display_mode: CalculatorDisplayMode::default(),
|
||||||
|
// calculator_alignment: CalculatorAlignment::default(),
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
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(),
|
|
||||||
state: CalculatorState::Normal,
|
|
||||||
undo_buf: vec![],
|
|
||||||
redo_buf: vec![],
|
|
||||||
active_macros: HashSet::new(),
|
|
||||||
registers: CalculatorRegisters::new(),
|
|
||||||
stack: settings.stack.into(),
|
|
||||||
macros: settings
|
|
||||||
.macros
|
|
||||||
.into_iter()
|
|
||||||
.map(|(key, mac)| {
|
|
||||||
Ok((
|
|
||||||
key.chars()
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| CalculatorError::LoadError(None))?,
|
|
||||||
mac,
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.collect::<CalculatorResult<CalculatorMacros>>()?,
|
|
||||||
constants: settings
|
|
||||||
.constants
|
|
||||||
.into_iter()
|
|
||||||
.map(|(key, constant)| {
|
|
||||||
Ok((
|
|
||||||
key.chars()
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| CalculatorError::LoadError(None))?,
|
|
||||||
constant,
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.collect::<CalculatorResult<CalculatorConstants>>()?,
|
|
||||||
angle_mode,
|
|
||||||
display_mode,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_config() -> CalculatorResult<Calculator> {
|
pub fn load_config() -> CalculatorResult<Calculator> {
|
||||||
let settings = load(APP_NAME).map_err(|e| CalculatorError::LoadError(Some(e)))?;
|
load(APP_NAME).map_err(|e| CalculatorError::LoadError(Some(e)))
|
||||||
Calculator::with_settings(settings)
|
|
||||||
}
|
}
|
||||||
pub fn save_config(&self) -> CalculatorResult<()> {
|
pub fn save_config(&self) -> CalculatorResult<()> {
|
||||||
let settings = CalculatorSettings {
|
store(APP_NAME, self).map_err(|e| CalculatorError::SaveError(Some(e)))
|
||||||
angle_mode: self.angle_mode.clone(),
|
|
||||||
display_mode: self.display_mode.clone(),
|
|
||||||
stack: self.stack.iter().map(|f| *f).collect(),
|
|
||||||
macros: self
|
|
||||||
.macros
|
|
||||||
.iter()
|
|
||||||
.map(|(key, mac)| (String::from(*key), mac.clone()))
|
|
||||||
.collect(),
|
|
||||||
constants: self
|
|
||||||
.constants
|
|
||||||
.iter()
|
|
||||||
.map(|(key, constant)| (String::from(*key), constant.clone()))
|
|
||||||
.collect(),
|
|
||||||
};
|
|
||||||
store(APP_NAME, settings).map_err(|e| CalculatorError::SaveError(Some(e)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_input(&mut self, c: char) -> CalculatorResult<()> {
|
pub fn take_input(&mut self, c: char) -> CalculatorResult<()> {
|
||||||
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),
|
||||||
//'!' => self.op(CalculatorOperation::Factorial),
|
|
||||||
'+' => self.op(CalculatorOperation::Add),
|
'+' => self.op(CalculatorOperation::Add),
|
||||||
'-' => self.op(CalculatorOperation::Subtract),
|
'-' => self.op(CalculatorOperation::Subtract),
|
||||||
'*' => self.op(CalculatorOperation::Multiply),
|
'*' => self.op(CalculatorOperation::Multiply),
|
||||||
@ -182,7 +173,6 @@ impl Calculator {
|
|||||||
'^' => self.op(CalculatorOperation::Pow),
|
'^' => self.op(CalculatorOperation::Pow),
|
||||||
'l' => self.op(CalculatorOperation::Log),
|
'l' => self.op(CalculatorOperation::Log),
|
||||||
'L' => self.op(CalculatorOperation::Ln),
|
'L' => self.op(CalculatorOperation::Ln),
|
||||||
//'e' => self.op(CalculatorOperation::E),
|
|
||||||
// Special
|
// Special
|
||||||
'u' => self.op(CalculatorOperation::Undo),
|
'u' => self.op(CalculatorOperation::Undo),
|
||||||
'U' => self.op(CalculatorOperation::Redo),
|
'U' => self.op(CalculatorOperation::Redo),
|
||||||
@ -277,10 +267,10 @@ impl Calculator {
|
|||||||
'd' => self.angle_mode = CalculatorAngleMode::Degrees,
|
'd' => self.angle_mode = CalculatorAngleMode::Degrees,
|
||||||
'r' => self.angle_mode = CalculatorAngleMode::Radians,
|
'r' => self.angle_mode = CalculatorAngleMode::Radians,
|
||||||
'g' => self.angle_mode = CalculatorAngleMode::Grads,
|
'g' => self.angle_mode = CalculatorAngleMode::Grads,
|
||||||
'_' => self.display_mode = CalculatorDisplayMode::Default(None),
|
'_' => self.display_mode = CalculatorDisplayMode::Default,
|
||||||
',' => self.display_mode = CalculatorDisplayMode::Default(Some(',')),
|
',' => self.display_mode = CalculatorDisplayMode::Separated(','),
|
||||||
' ' => self.display_mode = CalculatorDisplayMode::Default(Some(' ')),
|
' ' => self.display_mode = CalculatorDisplayMode::Separated(' '),
|
||||||
's' => self.display_mode = CalculatorDisplayMode::Scientific(3),
|
's' => self.display_mode = CalculatorDisplayMode::Scientific(DEFAULT_PRECISION),
|
||||||
'S' => {
|
'S' => {
|
||||||
let precision = self.checked_get(0)? as usize;
|
let precision = self.checked_get(0)? as usize;
|
||||||
if precision >= 20 {
|
if precision >= 20 {
|
||||||
@ -288,7 +278,9 @@ impl Calculator {
|
|||||||
}
|
}
|
||||||
self.display_mode = CalculatorDisplayMode::Scientific(self.pop_usize()?)
|
self.display_mode = CalculatorDisplayMode::Scientific(self.pop_usize()?)
|
||||||
}
|
}
|
||||||
'e' => self.display_mode = CalculatorDisplayMode::Engineering(3),
|
'e' => {
|
||||||
|
self.display_mode = CalculatorDisplayMode::Engineering(DEFAULT_PRECISION)
|
||||||
|
}
|
||||||
'E' => {
|
'E' => {
|
||||||
let precision = self.checked_get(0)? as usize;
|
let precision = self.checked_get(0)? as usize;
|
||||||
if precision >= 20 {
|
if precision >= 20 {
|
||||||
@ -296,6 +288,8 @@ impl Calculator {
|
|||||||
}
|
}
|
||||||
self.display_mode = CalculatorDisplayMode::Engineering(self.pop_usize()?)
|
self.display_mode = CalculatorDisplayMode::Engineering(self.pop_usize()?)
|
||||||
}
|
}
|
||||||
|
'f' => self.display_mode = CalculatorDisplayMode::Fixed(DEFAULT_PRECISION),
|
||||||
|
'F' => self.display_mode = CalculatorDisplayMode::Fixed(self.pop_usize()?),
|
||||||
_ => return Err(CalculatorError::NoSuchSetting(c)),
|
_ => return Err(CalculatorError::NoSuchSetting(c)),
|
||||||
};
|
};
|
||||||
self.state = CalculatorState::Normal;
|
self.state = CalculatorState::Normal;
|
||||||
@ -486,7 +480,6 @@ impl Calculator {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
CalculatorOperation::Sqrt => self.unary_op(|a| OpArgs::Unary(a.sqrt())),
|
CalculatorOperation::Sqrt => self.unary_op(|a| OpArgs::Unary(a.sqrt())),
|
||||||
// CalculatorOperation::Factorial => self.unary_op(|a| OpArgs::Unary(a.())),
|
|
||||||
CalculatorOperation::Log => self.unary_op(|a| OpArgs::Unary(a.log10())),
|
CalculatorOperation::Log => self.unary_op(|a| OpArgs::Unary(a.log10())),
|
||||||
CalculatorOperation::Ln => self.unary_op(|a| OpArgs::Unary(a.ln())),
|
CalculatorOperation::Ln => self.unary_op(|a| OpArgs::Unary(a.ln())),
|
||||||
CalculatorOperation::Pow => self.binary_op(|[a, b]| OpArgs::Unary(b.powf(a))),
|
CalculatorOperation::Pow => self.binary_op(|[a, b]| OpArgs::Unary(b.powf(a))),
|
||||||
@ -555,7 +548,6 @@ impl Calculator {
|
|||||||
} else {
|
} else {
|
||||||
MacroState::Start
|
MacroState::Start
|
||||||
});
|
});
|
||||||
// println!("{:?} {:?}", s, history_mode);
|
|
||||||
self.apply_state_change(s, forward)?;
|
self.apply_state_change(s, forward)?;
|
||||||
|
|
||||||
if history_mode == HistoryMode::One || macro_end {
|
if history_mode == HistoryMode::One || macro_end {
|
||||||
|
@ -55,6 +55,12 @@ pub enum CalculatorAngleMode {
|
|||||||
Grads,
|
Grads,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for CalculatorAngleMode {
|
||||||
|
fn default() -> Self {
|
||||||
|
CalculatorAngleMode::Degrees
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for CalculatorAngleMode {
|
impl fmt::Display for CalculatorAngleMode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
@ -65,136 +71,43 @@ impl fmt::Display for CalculatorAngleMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CalculatorAngleMode {
|
|
||||||
fn default() -> Self {
|
|
||||||
CalculatorAngleMode::Degrees
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(tag = "display_mode")]
|
#[serde(tag = "display_mode")]
|
||||||
pub enum CalculatorDisplayMode {
|
pub enum CalculatorDisplayMode {
|
||||||
Default(Option<char>),
|
Default,
|
||||||
|
Separated(char),
|
||||||
Scientific(usize),
|
Scientific(usize),
|
||||||
Engineering(usize),
|
Engineering(usize),
|
||||||
|
Fixed(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CalculatorDisplayMode {
|
impl fmt::Display for CalculatorDisplayMode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
CalculatorDisplayMode::Default(None) => write!(f, "DEF"),
|
CalculatorDisplayMode::Default => write!(f, "DEF"),
|
||||||
CalculatorDisplayMode::Default(Some(c)) => write!(f, "DEF({})", c),
|
CalculatorDisplayMode::Separated(c) => write!(f, "DEF({})", c),
|
||||||
CalculatorDisplayMode::Scientific(p) => write!(f, "SCI({})", p),
|
CalculatorDisplayMode::Scientific(p) => write!(f, "SCI({})", p),
|
||||||
CalculatorDisplayMode::Engineering(p) => write!(f, "ENG({})", p),
|
CalculatorDisplayMode::Engineering(p) => write!(f, "ENG({})", p),
|
||||||
|
CalculatorDisplayMode::Fixed(p) => write!(f, "FIX({})", p),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CalculatorDisplayMode {
|
impl Default for CalculatorDisplayMode {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
CalculatorDisplayMode::Default(None)
|
CalculatorDisplayMode::Default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
// #[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct CalculatorSettings {
|
// #[serde(tag = "calculator_alignment")]
|
||||||
// Order matters here as macros/constants cannot come first
|
// pub enum CalculatorAlignment {
|
||||||
pub stack: Vec<f64>,
|
// Right,
|
||||||
#[serde(skip)]
|
// Left,
|
||||||
pub display_mode: CalculatorDisplayMode,
|
// }
|
||||||
pub angle_mode: CalculatorAngleMode,
|
|
||||||
pub macros: HashMap<String, CalculatorMacro>,
|
|
||||||
pub constants: HashMap<String, CalculatorConstant>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for CalculatorSettings {
|
// impl Default for CalculatorAlignment {
|
||||||
fn default() -> CalculatorSettings {
|
// fn default() -> Self {
|
||||||
CalculatorSettings {
|
// CalculatorAlignment::Left
|
||||||
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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
13
src/main.rs
13
src/main.rs
@ -40,7 +40,7 @@ struct App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for App {
|
impl Default for App {
|
||||||
fn default() -> App {
|
fn default() -> Self {
|
||||||
let (calculator, error_msg) = match Calculator::load_config() {
|
let (calculator, error_msg) = match Calculator::load_config() {
|
||||||
Ok(c) => (c, None),
|
Ok(c) => (c, None),
|
||||||
Err(e) => (Calculator::default(), Some(format!("{}", e))),
|
Err(e) => (Calculator::default(), Some(format!("{}", e))),
|
||||||
@ -118,14 +118,17 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
.map(|(i, m)| {
|
.map(|(i, m)| {
|
||||||
let content = vec![Spans::from(Span::raw(
|
let content = vec![Spans::from(Span::raw(
|
||||||
match app.calculator.get_display_mode() {
|
match app.calculator.get_display_mode() {
|
||||||
CalculatorDisplayMode::Default(None) => format!("{:>2}: {}", i, *m),
|
CalculatorDisplayMode::Default => format!("{:>2}: {}", i, *m),
|
||||||
CalculatorDisplayMode::Default(Some(c)) => fmt_separated(i, *m, *c),
|
CalculatorDisplayMode::Separated(c) => fmt_separated(i, *m, *c),
|
||||||
CalculatorDisplayMode::Scientific(precision) => {
|
CalculatorDisplayMode::Scientific(precision) => {
|
||||||
fmt_scientific(i, *m, *precision)
|
fmt_scientific(i, *m, *precision)
|
||||||
}
|
}
|
||||||
CalculatorDisplayMode::Engineering(_precision) => {
|
CalculatorDisplayMode::Engineering(_precision) => {
|
||||||
format!("{:>2}: {}", i, m)
|
format!("{:>2}: {}", i, m)
|
||||||
}
|
}
|
||||||
|
CalculatorDisplayMode::Fixed(precision) => {
|
||||||
|
format!("{:>2}: {:.precision$}", i, m, precision = precision)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
))];
|
))];
|
||||||
ListItem::new(content)
|
ListItem::new(content)
|
||||||
@ -240,7 +243,9 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
s => Scientific\n\
|
s => Scientific\n\
|
||||||
S => Scientific (stack precision)\n\
|
S => Scientific (stack precision)\n\
|
||||||
e => Engineering\n\
|
e => Engineering\n\
|
||||||
E => Engineering (stack precision)\
|
E => Engineering (stack precision)\n\
|
||||||
|
f => Engineering\n\
|
||||||
|
F => Engineering (stack precision)\
|
||||||
",
|
",
|
||||||
},
|
},
|
||||||
f,
|
f,
|
||||||
|
@ -42,7 +42,7 @@ struct App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for App {
|
impl Default for App {
|
||||||
fn default() -> App {
|
fn default() -> Self {
|
||||||
App {
|
App {
|
||||||
input: String::new(),
|
input: String::new(),
|
||||||
input_mode: InputMode::Normal,
|
input_mode: InputMode::Normal,
|
||||||
|
@ -35,7 +35,7 @@ pub struct Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Config {
|
fn default() -> Self {
|
||||||
Config {
|
Config {
|
||||||
exit_key: Key::Char('q'),
|
exit_key: Key::Char('q'),
|
||||||
tick_rate: Duration::from_millis(250),
|
tick_rate: Duration::from_millis(250),
|
||||||
|
Loading…
Reference in New Issue
Block a user