use std::collections::HashMap;
pub struct Calculator {
history: Vec<String>,
cache: HashMap<String, f64>,
}
impl Default for Calculator {
fn default() -> Self {
Self::new()
}
}
impl Calculator {
pub fn new() -> Self {
Self {
history: Vec::new(),
cache: HashMap::new(),
}
}
pub fn add(&mut self, a: f64, b: f64) -> f64 {
let result = a + b;
self.history.push(format!("{a} + {b} = {result}"));
result
}
pub fn multiply(&mut self, a: f64, b: f64) -> f64 {
let result = a * b;
self.history.push(format!("{a} * {b} = {result}"));
result
}
pub fn factorial(&mut self, n: u32) -> u64 {
if n <= 1 {
1
} else {
n as u64 * self.factorial(n - 1)
}
}
pub fn get_history(&self) -> &Vec<String> {
&self.history
}
pub fn clear_history(&mut self) {
self.history.clear();
}
}
#[derive(Debug)]
pub enum CalculatorError {
DivisionByZero,
InvalidInput(String),
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut calc = Calculator::new();
let sum = calc.add(5.0, 3.0);
let product = calc.multiply(4.0, 7.0);
let fact = calc.factorial(5);
println!("Sum: {sum}");
println!("Product: {product}");
println!("Factorial: {fact}");
for entry in calc.get_history() {
println!("History: {entry}");
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_calculator_add() {
let mut calc = Calculator::new();
assert_eq!(calc.add(2.0, 3.0), 5.0);
}
#[test]
fn test_calculator_multiply() {
let mut calc = Calculator::new();
assert_eq!(calc.multiply(4.0, 5.0), 20.0);
}
#[test]
fn test_factorial() {
let mut calc = Calculator::new();
assert_eq!(calc.factorial(5), 120);
}
}