Started work on vectors
This commit is contained in:
parent
bfae3cafce
commit
e05b0726f1
21
src/calc.rs
21
src/calc.rs
@ -186,6 +186,8 @@ impl Calculator {
|
|||||||
CalculatorState::WaitingForSetting => self.setting_input(c),
|
CalculatorState::WaitingForSetting => self.setting_input(c),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// This function is very long, but it is just a match, so it should be fine
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
fn normal_input(&mut self, c: char) -> CalculatorResult<()> {
|
fn normal_input(&mut self, c: char) -> CalculatorResult<()> {
|
||||||
match c {
|
match c {
|
||||||
c @ '0'..='9' | c @ '.' | c @ 'e' => match c {
|
c @ '0'..='9' | c @ '.' | c @ 'e' => match c {
|
||||||
@ -194,11 +196,7 @@ impl Calculator {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
'e' => {
|
'e' => {
|
||||||
if self.l.is_empty() {
|
self.edit()?;
|
||||||
let f = self.pop().or(Err(CalculatorError::NotEnoughStackEntries))?;
|
|
||||||
|
|
||||||
self.l = f.to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.l.contains('e') {
|
if !self.l.contains('e') {
|
||||||
self.l.push('e');
|
self.l.push('e');
|
||||||
@ -437,10 +435,15 @@ impl Calculator {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.l = self
|
// Temporary check to see if we can get an editable string
|
||||||
.pop()
|
let str = self.peek(0)?.to_editable_string()?;
|
||||||
.or(Err(CalculatorError::NotEnoughStackEntries))?
|
|
||||||
.to_string();
|
// If we got here, then there was no error. Pop
|
||||||
|
self.pop()?;
|
||||||
|
|
||||||
|
// Set l after popping
|
||||||
|
self.l = str;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
/// Get the value of l
|
/// Get the value of l
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// use super::operations::CalculatorStateChange;
|
// TODO: Clippy is recommending pass by value instead of by ref, but I plan to add imaginary numbers, which will change this
|
||||||
// TODO: This file kina blows. Tons of repetition. Do not know how to fix yet though
|
#![allow(clippy::trivially_copy_pass_by_ref)]
|
||||||
use super::errors::{CalculatorError, CalculatorResult};
|
use super::errors::{CalculatorError, CalculatorResult};
|
||||||
use super::types::CalculatorAngleMode;
|
use super::types::CalculatorAngleMode;
|
||||||
use crate::calc::CalculatorDisplayMode;
|
use crate::calc::CalculatorDisplayMode;
|
||||||
@ -12,15 +12,6 @@ pub struct Number {
|
|||||||
pub value: f64,
|
pub value: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Number {
|
|
||||||
fn binary_op(arg: &Entry, op: impl Fn(&Number) -> Number) -> CalculatorResult<Entry> {
|
|
||||||
match arg {
|
|
||||||
Entry::Number(number) => Ok(Entry::Number(op(number))),
|
|
||||||
Entry::Vector(vector) => Ok(vector.map_into(op)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for Number {
|
impl PartialEq for Number {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
if self.value.is_nan() && other.value.is_nan()
|
if self.value.is_nan() && other.value.is_nan()
|
||||||
@ -45,41 +36,6 @@ pub struct Vector {
|
|||||||
pub values: Vec<Number>,
|
pub values: Vec<Number>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vector {
|
|
||||||
fn binary_op(
|
|
||||||
&self,
|
|
||||||
arg: &Entry,
|
|
||||||
op: impl Fn((&Number, &Number)) -> Number,
|
|
||||||
) -> CalculatorResult<Entry> {
|
|
||||||
match arg {
|
|
||||||
// Entry::Number(number) => Ok(Entry::Number(op(number))),
|
|
||||||
Entry::Number(number) => Ok(self.map_into(|t| op((t, number)))),
|
|
||||||
Entry::Vector(vector) => {
|
|
||||||
if self.values.len() != vector.values.len() {
|
|
||||||
return Err(CalculatorError::ArithmeticError);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Entry::Vector(Vector {
|
|
||||||
values: self
|
|
||||||
.values
|
|
||||||
.iter()
|
|
||||||
.zip(vector.values.iter())
|
|
||||||
.map(op)
|
|
||||||
.collect(),
|
|
||||||
..*self
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_into(&self, op: impl Fn(&Number) -> Number) -> Entry {
|
|
||||||
Entry::Vector(Vector {
|
|
||||||
values: (self.values.iter().map(op).collect()),
|
|
||||||
..*self
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum Entry {
|
pub enum Entry {
|
||||||
@ -88,7 +44,28 @@ pub enum Entry {
|
|||||||
// Matrix(Vec<Vec<Number>>),
|
// Matrix(Vec<Vec<Number>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// macro_rules! op_child_call {
|
||||||
|
// ($a:ident, $op:ident) => {
|
||||||
|
// match $a {
|
||||||
|
// Self::Number(number) => number.$op(),
|
||||||
|
// Self::Vector(vector) => vector.$op(),
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// ($a:ident, $op:ident, $arg:expr) => {
|
||||||
|
// match $a {
|
||||||
|
// Self::Number(number) => number.$op($arg),
|
||||||
|
// Self::Vector(vector) => vector.$op($arg),
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
impl CalculatorEntry for Entry {
|
impl CalculatorEntry for Entry {
|
||||||
|
fn to_editable_string(&self) -> CalculatorResult<String> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.to_editable_string(),
|
||||||
|
Self::Vector(vector) => vector.to_editable_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String {
|
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::Number(number) => number.format_entry(display_mode),
|
Self::Number(number) => number.format_entry(display_mode),
|
||||||
@ -101,36 +78,6 @@ impl CalculatorEntry for Entry {
|
|||||||
Self::Vector(vector) => vector.is_valid(),
|
Self::Vector(vector) => vector.is_valid(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn add(&self, arg: &Self) -> CalculatorResult<Self> {
|
|
||||||
match self {
|
|
||||||
Self::Number(number) => number.add(arg),
|
|
||||||
Self::Vector(vector) => vector.add(arg),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn sub(&self, arg: &Self) -> CalculatorResult<Self> {
|
|
||||||
match self {
|
|
||||||
Self::Number(number) => number.sub(arg),
|
|
||||||
Self::Vector(vector) => vector.sub(arg),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn mul(&self, arg: &Self) -> CalculatorResult<Self> {
|
|
||||||
match self {
|
|
||||||
Self::Number(number) => number.mul(arg),
|
|
||||||
Self::Vector(vector) => vector.mul(arg),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn div(&self, arg: &Self) -> CalculatorResult<Self> {
|
|
||||||
match self {
|
|
||||||
Self::Number(number) => number.div(arg),
|
|
||||||
Self::Vector(vector) => vector.div(arg),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn int_divide(&self, arg: &Self) -> CalculatorResult<Self> {
|
|
||||||
match self {
|
|
||||||
Self::Number(number) => number.int_divide(arg),
|
|
||||||
Self::Vector(vector) => vector.int_divide(arg),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn negate(&self) -> CalculatorResult<Self> {
|
fn negate(&self) -> CalculatorResult<Self> {
|
||||||
match self {
|
match self {
|
||||||
Self::Number(number) => number.negate(),
|
Self::Number(number) => number.negate(),
|
||||||
@ -149,12 +96,6 @@ impl CalculatorEntry for Entry {
|
|||||||
Self::Vector(vector) => vector.inverse(),
|
Self::Vector(vector) => vector.inverse(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn modulo(&self, arg: &Self) -> CalculatorResult<Self> {
|
|
||||||
match self {
|
|
||||||
Self::Number(number) => number.modulo(arg),
|
|
||||||
Self::Vector(vector) => vector.modulo(arg),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> {
|
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Self> {
|
||||||
match self {
|
match self {
|
||||||
Self::Number(number) => number.sin(angle_mode),
|
Self::Number(number) => number.sin(angle_mode),
|
||||||
@ -209,15 +150,141 @@ impl CalculatorEntry for Entry {
|
|||||||
Self::Vector(vector) => vector.ln(),
|
Self::Vector(vector) => vector.ln(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add(&self, arg: &Self) -> CalculatorResult<Self> {
|
||||||
|
match arg {
|
||||||
|
Self::Number(number) => self.add_num(number),
|
||||||
|
Self::Vector(vector) => self.add_vec(vector),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn sub(&self, arg: &Self) -> CalculatorResult<Self> {
|
||||||
|
match arg {
|
||||||
|
Self::Number(number) => self.sub_num(number),
|
||||||
|
Self::Vector(vector) => self.sub_vec(vector),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn mul(&self, arg: &Self) -> CalculatorResult<Self> {
|
||||||
|
match arg {
|
||||||
|
Self::Number(number) => self.mul_num(number),
|
||||||
|
Self::Vector(vector) => self.mul_vec(vector),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn div(&self, arg: &Self) -> CalculatorResult<Self> {
|
||||||
|
match arg {
|
||||||
|
Self::Number(number) => self.div_num(number),
|
||||||
|
Self::Vector(vector) => self.div_vec(vector),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn int_divide(&self, arg: &Self) -> CalculatorResult<Self> {
|
||||||
|
match arg {
|
||||||
|
Self::Number(number) => self.int_divide_num(number),
|
||||||
|
Self::Vector(vector) => self.int_divide_vec(vector),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn modulo(&self, arg: &Self) -> CalculatorResult<Self> {
|
||||||
|
match arg {
|
||||||
|
Self::Number(number) => self.modulo_num(number),
|
||||||
|
Self::Vector(vector) => self.modulo_vec(vector),
|
||||||
|
}
|
||||||
|
}
|
||||||
fn pow(&self, arg: &Self) -> CalculatorResult<Self> {
|
fn pow(&self, arg: &Self) -> CalculatorResult<Self> {
|
||||||
|
match arg {
|
||||||
|
Self::Number(number) => self.pow_num(number),
|
||||||
|
Self::Vector(vector) => self.pow_vec(vector),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_vec(&self, arg: &Vector) -> CalculatorResult<Self> {
|
||||||
match self {
|
match self {
|
||||||
Self::Number(number) => number.pow(arg),
|
Self::Number(number) => number.add_vec(arg),
|
||||||
Self::Vector(vector) => vector.pow(arg),
|
Self::Vector(vector) => vector.add_vec(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn sub_vec(&self, arg: &Vector) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.sub_vec(arg),
|
||||||
|
Self::Vector(vector) => vector.sub_vec(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn mul_vec(&self, arg: &Vector) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.mul_vec(arg),
|
||||||
|
Self::Vector(vector) => vector.mul_vec(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn div_vec(&self, arg: &Vector) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.div_vec(arg),
|
||||||
|
Self::Vector(vector) => vector.div_vec(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn int_divide_vec(&self, arg: &Vector) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.int_divide_vec(arg),
|
||||||
|
Self::Vector(vector) => vector.int_divide_vec(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn modulo_vec(&self, arg: &Vector) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.modulo_vec(arg),
|
||||||
|
Self::Vector(vector) => vector.modulo_vec(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn pow_vec(&self, arg: &Vector) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.pow_vec(arg),
|
||||||
|
Self::Vector(vector) => vector.pow_vec(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_num(&self, arg: &Number) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.add_num(arg),
|
||||||
|
Self::Vector(vector) => vector.add_num(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn sub_num(&self, arg: &Number) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.sub_num(arg),
|
||||||
|
Self::Vector(vector) => vector.sub_num(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn mul_num(&self, arg: &Number) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.mul_num(arg),
|
||||||
|
Self::Vector(vector) => vector.mul_num(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn div_num(&self, arg: &Number) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.div_num(arg),
|
||||||
|
Self::Vector(vector) => vector.div_num(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn int_divide_num(&self, arg: &Number) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.int_divide_num(arg),
|
||||||
|
Self::Vector(vector) => vector.int_divide_num(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn modulo_num(&self, arg: &Number) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.modulo_num(arg),
|
||||||
|
Self::Vector(vector) => vector.modulo_num(arg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn pow_num(&self, arg: &Number) -> CalculatorResult<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Number(number) => number.pow_num(arg),
|
||||||
|
Self::Vector(vector) => vector.pow_num(arg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CalculatorEntry for Number {
|
impl CalculatorEntry for Number {
|
||||||
|
fn to_editable_string(&self) -> CalculatorResult<String> {
|
||||||
|
Ok(format!("{}", self.value))
|
||||||
|
}
|
||||||
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String {
|
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String {
|
||||||
match display_mode {
|
match display_mode {
|
||||||
CalculatorDisplayMode::Default => format!("{}", self.value),
|
CalculatorDisplayMode::Default => format!("{}", self.value),
|
||||||
@ -232,31 +299,6 @@ impl CalculatorEntry for Number {
|
|||||||
fn is_valid(&self) -> bool {
|
fn is_valid(&self) -> bool {
|
||||||
!self.value.is_nan() && !self.value.is_infinite()
|
!self.value.is_nan() && !self.value.is_infinite()
|
||||||
}
|
}
|
||||||
fn add(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
Number::binary_op(&arg, |b| Self {
|
|
||||||
value: b.value + self.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn sub(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
Number::binary_op(&arg, |b| Self {
|
|
||||||
value: b.value - self.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn mul(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
Number::binary_op(&arg, |b| Self {
|
|
||||||
value: b.value * self.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn div(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
Number::binary_op(&arg, |b| Self {
|
|
||||||
value: b.value / self.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn int_divide(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
Number::binary_op(&arg, |b| Self {
|
|
||||||
value: b.value.div_euclid(self.value),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn negate(&self) -> CalculatorResult<Entry> {
|
fn negate(&self) -> CalculatorResult<Entry> {
|
||||||
Ok(Entry::Number(Self { value: -self.value }))
|
Ok(Entry::Number(Self { value: -self.value }))
|
||||||
}
|
}
|
||||||
@ -270,11 +312,6 @@ impl CalculatorEntry for Number {
|
|||||||
value: self.value.recip(),
|
value: self.value.recip(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
fn modulo(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
Number::binary_op(&arg, |b| Self {
|
|
||||||
value: b.value % self.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
|
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
|
||||||
Ok(Entry::Number(Self {
|
Ok(Entry::Number(Self {
|
||||||
value: match angle_mode {
|
value: match angle_mode {
|
||||||
@ -344,21 +381,142 @@ impl CalculatorEntry for Number {
|
|||||||
value: self.value.ln(),
|
value: self.value.ln(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.add_vec(vector),
|
||||||
|
Entry::Number(number) => self.add_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn sub(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.sub_vec(vector),
|
||||||
|
Entry::Number(number) => self.sub_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn mul(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.mul_vec(vector),
|
||||||
|
Entry::Number(number) => self.mul_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn div(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.div_vec(vector),
|
||||||
|
Entry::Number(number) => self.div_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn int_divide(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.int_divide_vec(vector),
|
||||||
|
Entry::Number(number) => self.int_divide_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn modulo(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.modulo_vec(vector),
|
||||||
|
Entry::Number(number) => self.modulo_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
fn pow(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
fn pow(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
Number::binary_op(&arg, |b| Self {
|
match arg {
|
||||||
value: b.value.powf(self.value),
|
Entry::Vector(vector) => self.pow_vec(vector),
|
||||||
|
Entry::Number(number) => self.pow_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_vec(&self, arg: &Vector) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary(arg, Self::add_num)
|
||||||
|
}
|
||||||
|
fn sub_vec(&self, arg: &Vector) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary(arg, Self::sub_num)
|
||||||
|
}
|
||||||
|
fn mul_vec(&self, arg: &Vector) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary(arg, Self::mul_num)
|
||||||
|
}
|
||||||
|
fn div_vec(&self, arg: &Vector) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary(arg, Self::div_num)
|
||||||
|
}
|
||||||
|
fn int_divide_vec(&self, arg: &Vector) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary(arg, Self::int_divide_num)
|
||||||
|
}
|
||||||
|
fn modulo_vec(&self, arg: &Vector) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary(arg, Self::modulo_num)
|
||||||
|
}
|
||||||
|
fn pow_vec(&self, arg: &Vector) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary(arg, Self::pow_num)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Number(Self {
|
||||||
|
value: arg.value + self.value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn sub_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Number(Self {
|
||||||
|
value: arg.value - self.value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn mul_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Number(Self {
|
||||||
|
value: arg.value * self.value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn div_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Number(Self {
|
||||||
|
value: arg.value / self.value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn int_divide_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Number(Self {
|
||||||
|
value: arg.value.div_euclid(self.value),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn modulo_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Number(Self {
|
||||||
|
value: arg.value % self.value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn pow_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Number(Self {
|
||||||
|
value: arg.value.powf(self.value),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Number {
|
||||||
|
fn iterated_binary(
|
||||||
|
self,
|
||||||
|
vector: &Vector,
|
||||||
|
op: impl Fn(&Self, &Self) -> CalculatorResult<Entry>,
|
||||||
|
) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Vector(Vector {
|
||||||
|
values: vector
|
||||||
|
.values
|
||||||
|
.iter()
|
||||||
|
.map(|n| op(&self, n))
|
||||||
|
.map(|e| match e {
|
||||||
|
// Only numbers are valid in a vector
|
||||||
|
Ok(Entry::Number(number)) => Ok(number),
|
||||||
|
_ => Err(CalculatorError::ArithmeticError),
|
||||||
})
|
})
|
||||||
|
.collect::<CalculatorResult<Vec<Self>>>()?,
|
||||||
|
direction: vector.direction,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CalculatorEntry for Vector {
|
impl CalculatorEntry for Vector {
|
||||||
// Misc
|
// Misc
|
||||||
|
fn to_editable_string(&self) -> CalculatorResult<String> {
|
||||||
|
// TODO: Eventualy we can parse and edit a vector as a string
|
||||||
|
Err(CalculatorError::TypeMismatch)
|
||||||
|
}
|
||||||
fn is_valid(&self) -> bool {
|
fn is_valid(&self) -> bool {
|
||||||
!self
|
self.values
|
||||||
.values
|
|
||||||
.iter()
|
.iter()
|
||||||
.find(|number| !number.is_valid())
|
.find(|number| !number.is_valid())
|
||||||
.is_some()
|
.is_none()
|
||||||
}
|
}
|
||||||
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String {
|
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String {
|
||||||
format!(
|
format!(
|
||||||
@ -371,80 +529,237 @@ impl CalculatorEntry for Vector {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Mathematical operations
|
// Mathematical operations
|
||||||
fn add(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
self.binary_op(&arg, |(a, b)| Number {
|
|
||||||
value: b.value + a.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn sub(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
self.binary_op(&arg, |(a, b)| Number {
|
|
||||||
value: b.value - a.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn mul(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
self.binary_op(&arg, |(a, b)| Number {
|
|
||||||
value: b.value * a.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn div(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
self.binary_op(&arg, |(a, b)| Number {
|
|
||||||
value: b.value / a.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn int_divide(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
|
||||||
self.binary_op(&arg, |(a, b)| Number {
|
|
||||||
value: b.value.div_euclid(a.value),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn negate(&self) -> CalculatorResult<Entry> {
|
fn negate(&self) -> CalculatorResult<Entry> {
|
||||||
Ok(self.map_into(|n| Number { value: -n.value }))
|
self.iterated_unary(Number::negate)
|
||||||
}
|
}
|
||||||
fn abs(&self) -> CalculatorResult<Entry> {
|
fn abs(&self) -> CalculatorResult<Entry> {
|
||||||
Ok(self.map_into(|n| Number {
|
self.iterated_unary(Number::abs)
|
||||||
value: n.value.abs(),
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
fn inverse(&self) -> CalculatorResult<Entry> {
|
fn inverse(&self) -> CalculatorResult<Entry> {
|
||||||
Ok(Entry::Vector(Vector {
|
self.iterated_unary(Number::inverse)
|
||||||
direction: !self.direction,
|
}
|
||||||
..*self
|
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
|
||||||
}))
|
self.iterated_unary(|n| n.sin(angle_mode))
|
||||||
|
}
|
||||||
|
fn cos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_unary(|n| n.cos(angle_mode))
|
||||||
|
}
|
||||||
|
fn tan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_unary(|n| n.tan(angle_mode))
|
||||||
|
}
|
||||||
|
fn asin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_unary(|n| n.asin(angle_mode))
|
||||||
|
}
|
||||||
|
fn acos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_unary(|n| n.acos(angle_mode))
|
||||||
|
}
|
||||||
|
fn atan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_unary(|n| n.atan(angle_mode))
|
||||||
|
}
|
||||||
|
fn sqrt(&self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_unary(Number::sqrt)
|
||||||
|
}
|
||||||
|
fn log(&self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_unary(Number::log)
|
||||||
|
}
|
||||||
|
fn ln(&self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_unary(Number::ln)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.add_vec(vector),
|
||||||
|
Entry::Number(number) => self.add_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn sub(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.sub_vec(vector),
|
||||||
|
Entry::Number(number) => self.sub_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn mul(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.mul_vec(vector),
|
||||||
|
Entry::Number(number) => self.mul_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn div(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.div_vec(vector),
|
||||||
|
Entry::Number(number) => self.div_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn int_divide(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
|
match arg {
|
||||||
|
Entry::Vector(vector) => self.int_divide_vec(vector),
|
||||||
|
Entry::Number(number) => self.int_divide_num(number),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn modulo(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
fn modulo(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
self.binary_op(&arg, |(a, b)| Number {
|
match arg {
|
||||||
value: b.value % a.value,
|
Entry::Vector(vector) => self.modulo_vec(vector),
|
||||||
})
|
Entry::Number(number) => self.modulo_num(number),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
|
|
||||||
fn cos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
|
|
||||||
fn tan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
|
|
||||||
fn asin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
|
|
||||||
fn acos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
|
|
||||||
fn atan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {}
|
|
||||||
fn sqrt(&self) -> CalculatorResult<Entry> {}
|
|
||||||
fn log(&self) -> CalculatorResult<Entry> {}
|
|
||||||
fn ln(&self) -> CalculatorResult<Entry> {}
|
|
||||||
fn pow(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
fn pow(&self, arg: &Entry) -> CalculatorResult<Entry> {
|
||||||
self.binary_op(&arg, |(a, b)| Number {
|
match arg {
|
||||||
value: b.value.powf(a.value),
|
Entry::Vector(vector) => self.pow_vec(vector),
|
||||||
})
|
Entry::Number(number) => self.pow_num(number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_vec(&self, arg: &Self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_vec(arg, Number::add_num)
|
||||||
|
}
|
||||||
|
fn sub_vec(&self, arg: &Self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_vec(arg, Number::sub_num)
|
||||||
|
}
|
||||||
|
fn mul_vec(&self, arg: &Self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_vec(arg, Number::mul_num)
|
||||||
|
}
|
||||||
|
fn div_vec(&self, arg: &Self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_vec(arg, Number::div_num)
|
||||||
|
}
|
||||||
|
fn int_divide_vec(&self, arg: &Self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_vec(arg, Number::int_divide_num)
|
||||||
|
}
|
||||||
|
fn modulo_vec(&self, arg: &Self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_vec(arg, Number::modulo_num)
|
||||||
|
}
|
||||||
|
fn pow_vec(&self, arg: &Self) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_vec(arg, Number::pow_num)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_num(arg, Number::add_num)
|
||||||
|
}
|
||||||
|
fn sub_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_num(arg, Number::sub_num)
|
||||||
|
}
|
||||||
|
fn mul_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_num(arg, Number::mul_num)
|
||||||
|
}
|
||||||
|
fn div_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_num(arg, Number::div_num)
|
||||||
|
}
|
||||||
|
fn int_divide_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_num(arg, Number::int_divide_num)
|
||||||
|
}
|
||||||
|
fn modulo_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_num(arg, Number::modulo_num)
|
||||||
|
}
|
||||||
|
fn pow_num(&self, arg: &Number) -> CalculatorResult<Entry> {
|
||||||
|
self.iterated_binary_num(arg, Number::pow_num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CalculatorEntry {
|
impl Vector {
|
||||||
|
fn iterated_unary(
|
||||||
|
&self,
|
||||||
|
op: impl Fn(&Number) -> CalculatorResult<Entry>,
|
||||||
|
) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Vector(Self {
|
||||||
|
values: self
|
||||||
|
.values
|
||||||
|
.iter()
|
||||||
|
.map(|n| op(n))
|
||||||
|
.map(|e| match e {
|
||||||
|
// Only numbers are valid in a vector
|
||||||
|
Ok(Entry::Number(number)) => Ok(number),
|
||||||
|
_ => Err(CalculatorError::ArithmeticError),
|
||||||
|
})
|
||||||
|
.collect::<CalculatorResult<Vec<Number>>>()?,
|
||||||
|
direction: true,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iterated_binary_vec(
|
||||||
|
&self,
|
||||||
|
v2: &Self,
|
||||||
|
op: impl Fn(&Number, &Number) -> CalculatorResult<Entry>,
|
||||||
|
) -> CalculatorResult<Entry> {
|
||||||
|
if self.values.len() != v2.values.len() {
|
||||||
|
return Err(CalculatorError::ArithmeticError);
|
||||||
|
}
|
||||||
|
if self.direction != v2.direction {
|
||||||
|
// TODO: Return a different error
|
||||||
|
return Err(CalculatorError::ArithmeticError);
|
||||||
|
}
|
||||||
|
Ok(Entry::Vector(Self {
|
||||||
|
values: self
|
||||||
|
.values
|
||||||
|
.iter()
|
||||||
|
.zip(v2.values.iter())
|
||||||
|
.map(|(n1, n2)| op(n1, n2))
|
||||||
|
.map(|e| match e {
|
||||||
|
// Only numbers are valid in a vector
|
||||||
|
Ok(Entry::Number(number)) => Ok(number),
|
||||||
|
_ => Err(CalculatorError::ArithmeticError),
|
||||||
|
})
|
||||||
|
.collect::<CalculatorResult<Vec<Number>>>()?,
|
||||||
|
direction: true,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn iterated_binary_num(
|
||||||
|
&self,
|
||||||
|
n2: &Number,
|
||||||
|
op: impl Fn(&Number, &Number) -> CalculatorResult<Entry>,
|
||||||
|
) -> CalculatorResult<Entry> {
|
||||||
|
Ok(Entry::Vector(Self {
|
||||||
|
values: self
|
||||||
|
.values
|
||||||
|
.iter()
|
||||||
|
.map(|n| op(n, n2))
|
||||||
|
.map(|e| match e {
|
||||||
|
// Only numbers are valid in a vector
|
||||||
|
Ok(Entry::Number(number)) => Ok(number),
|
||||||
|
_ => Err(CalculatorError::ArithmeticError),
|
||||||
|
})
|
||||||
|
.collect::<CalculatorResult<Vec<Number>>>()?,
|
||||||
|
direction: true,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait CalculatorEntry
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
// Misc
|
// Misc
|
||||||
fn is_valid(&self) -> bool;
|
fn is_valid(&self) -> bool;
|
||||||
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String;
|
fn format_entry(&self, display_mode: &CalculatorDisplayMode) -> String;
|
||||||
|
fn to_editable_string(&self) -> CalculatorResult<String>;
|
||||||
// Mathematical operations
|
// Mathematical operations
|
||||||
|
// Binary
|
||||||
fn add(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
fn add(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
||||||
fn sub(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
fn sub(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
||||||
fn mul(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
fn mul(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
||||||
fn div(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
fn div(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
||||||
fn int_divide(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
fn int_divide(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
||||||
|
fn modulo(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
||||||
|
fn pow(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
||||||
|
|
||||||
|
fn add_vec(&self, arg: &Vector) -> CalculatorResult<Entry>;
|
||||||
|
fn sub_vec(&self, arg: &Vector) -> CalculatorResult<Entry>;
|
||||||
|
fn mul_vec(&self, arg: &Vector) -> CalculatorResult<Entry>;
|
||||||
|
fn div_vec(&self, arg: &Vector) -> CalculatorResult<Entry>;
|
||||||
|
fn int_divide_vec(&self, arg: &Vector) -> CalculatorResult<Entry>;
|
||||||
|
fn modulo_vec(&self, arg: &Vector) -> CalculatorResult<Entry>;
|
||||||
|
fn pow_vec(&self, arg: &Vector) -> CalculatorResult<Entry>;
|
||||||
|
|
||||||
|
fn add_num(&self, arg: &Number) -> CalculatorResult<Entry>;
|
||||||
|
fn sub_num(&self, arg: &Number) -> CalculatorResult<Entry>;
|
||||||
|
fn mul_num(&self, arg: &Number) -> CalculatorResult<Entry>;
|
||||||
|
fn div_num(&self, arg: &Number) -> CalculatorResult<Entry>;
|
||||||
|
fn int_divide_num(&self, arg: &Number) -> CalculatorResult<Entry>;
|
||||||
|
fn modulo_num(&self, arg: &Number) -> CalculatorResult<Entry>;
|
||||||
|
fn pow_num(&self, arg: &Number) -> CalculatorResult<Entry>;
|
||||||
|
|
||||||
|
// Unary
|
||||||
fn negate(&self) -> CalculatorResult<Entry>;
|
fn negate(&self) -> CalculatorResult<Entry>;
|
||||||
fn abs(&self) -> CalculatorResult<Entry>;
|
fn abs(&self) -> CalculatorResult<Entry>;
|
||||||
fn inverse(&self) -> CalculatorResult<Entry>;
|
fn inverse(&self) -> CalculatorResult<Entry>;
|
||||||
fn modulo(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
|
||||||
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry>;
|
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry>;
|
||||||
fn cos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry>;
|
fn cos(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry>;
|
||||||
fn tan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry>;
|
fn tan(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry>;
|
||||||
@ -454,13 +769,13 @@ pub trait CalculatorEntry {
|
|||||||
fn sqrt(&self) -> CalculatorResult<Entry>;
|
fn sqrt(&self) -> CalculatorResult<Entry>;
|
||||||
fn log(&self) -> CalculatorResult<Entry>;
|
fn log(&self) -> CalculatorResult<Entry>;
|
||||||
fn ln(&self) -> CalculatorResult<Entry>;
|
fn ln(&self) -> CalculatorResult<Entry>;
|
||||||
fn pow(&self, arg: &Entry) -> CalculatorResult<Entry>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Entry {
|
impl fmt::Display for Entry {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Number(Number { value }) => write!(f, "{}", value),
|
Self::Number(number) => write!(f, "{}", number),
|
||||||
|
Self::Vector(vector) => write!(f, "{}", vector),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,6 +786,20 @@ impl fmt::Display for Number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Vector {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"[{}]",
|
||||||
|
self.values
|
||||||
|
.iter()
|
||||||
|
.map(|number| format!("{}", number))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("; ")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Based on https://stackoverflow.com/a/65266882
|
// Based on https://stackoverflow.com/a/65266882
|
||||||
fn scientific(f: f64, precision: usize) -> String {
|
fn scientific(f: f64, precision: usize) -> String {
|
||||||
let mut ret = format!("{:.precision$E}", f, precision = precision);
|
let mut ret = format!("{:.precision$E}", f, precision = precision);
|
||||||
|
@ -135,7 +135,13 @@ impl App {
|
|||||||
.calculator
|
.calculator
|
||||||
.registers
|
.registers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(key, value)| format!("{}: {}", key, value))
|
.map(|(key, value)| {
|
||||||
|
format!(
|
||||||
|
"{}: {}",
|
||||||
|
key,
|
||||||
|
value.format_entry(&self.calculator.display_mode)
|
||||||
|
)
|
||||||
|
})
|
||||||
.fold(String::new(), |acc, s| acc + &s + "\n")
|
.fold(String::new(), |acc, s| acc + &s + "\n")
|
||||||
.trim_end(),
|
.trim_end(),
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user