use std::{
fmt,
io::{self, Write},
ops,
};
#[derive(Clone, Debug)]
struct Operand(Vec<u8>);
impl Operand {
fn new() -> Self {
Self(Vec::new())
}
}
impl From<&str> for Operand {
fn from(operand: &str) -> Self {
let mut storage = Self::new();
for c in operand.chars().rev() {
let n = c
.to_digit(10)
.expect("Operands must be a number in base 10");
storage.0.push(n as u8);
}
storage
}
}
impl From<&Operand> for String {
fn from(operand: &Operand) -> Self {
let mut s = String::new();
for n in operand.0.clone().iter().rev() {
s.push_str(&n.to_string());
}
if s.len() == 0 {
s.push_str("0");
}
s
}
}
impl ops::Add<Operand> for Operand {
type Output = Operand;
fn add(self, rhs: Operand) -> Self {
let mut lhs = self.0;
let mut rhs = rhs.0;
let max = lhs.len().max(rhs.len());
lhs.resize(max, 0);
rhs.resize(max, 0);
let mut result = Vec::new();
let mut carry = 0;
for (a, b) in lhs.iter().zip(rhs.iter()) {
let mut r = a + b + carry;
if r > 9 {
r = r - 10;
carry = 1;
} else {
carry = 0;
}
result.push(r);
}
if carry > 0 {
result.push(carry);
}
Operand(result)
}
}
impl fmt::Display for Operand {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", String::from(self))
}
}
#[derive(Clone, Debug)]
enum Operator {
Add,
Sub,
Mul,
Div,
Non,
}
impl Operator {
fn new() -> Self {
Self::Non
}
}
impl From<&str> for Operator {
fn from(operator: &str) -> Self {
match operator {
"+" => Operator::Add,
"-" => Operator::Sub,
"*" => Operator::Mul,
"/" => Operator::Div,
"," => Operator::Non,
_ => Operator::new(),
}
}
}
impl From<&Operator> for String {
fn from(operator: &Operator) -> Self {
match operator {
Operator::Add => "+",
Operator::Sub => "-",
Operator::Mul => "*",
Operator::Div => "/",
Operator::Non => ",",
}
.to_string()
}
}
impl fmt::Display for Operator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", String::from(self))
}
}
fn main() {
let mut operand1: String = String::new();
let mut operand2: String = String::new();
let mut operator: String = String::new();
print!("Enter the first operand: ");
io::stdout().flush().unwrap();
io::stdin()
.read_line(&mut operand1)
.expect("Failed to read the first operand");
print!("Enter the second operand: ");
io::stdout().flush().unwrap();
io::stdin()
.read_line(&mut operand2)
.expect("Failed to read the second operand");
print!("Enter the operator (+, -, *, /, or else): ");
io::stdout().flush().unwrap();
io::stdin()
.read_line(&mut operator)
.expect("Failed to read the operator");
let operand1: Operand = operand1.trim().into();
let operand2: Operand = operand2.trim().into();
let operator: Operator = operator.trim().into();
print!("{} {} {} = ", &operand1, &operator, &operand2);
println!("{}", operand1 + operand2);
}