
Complex Number Calculator in Rust
Your Favourite Calculator in Rust
To get started in Rust, I implemented a calendar. It can perform calculations with real numbers as well as with complex numbers. It also provides some functions for calculating sums or products. I then used egui to create a GUI for it.


Users can save the arithmetic expression and its result to a file.

The source code of my calculator can be extended easily to work with any solid, not just real or complex numbers. Therefore, I moved the code for performing the actual calculations into a Rust Trait solid.
pub trait Solid<T : SolidNumber<T>> : Sized {
//general info
fn get_solid_name() -> String;
//addition
fn get_neutral_element_addition() -> T;
fn add(x : T, y : T) -> T;
fn get_additive_inverse(x : T) -> T;
//multiplication
fn get_neutral_element_multiplicative() -> T;
fn multiply(x : T, y : T) -> T;
fn get_multiplicative_inverse(x : T) -> T;
//other functions
fn get_available_functions() -> Vec<(String, fn(Vec<String>)->(T, String), Vec<i32>, i32)>;
}This generic traits is used for implementing real and complex numbers:
use std::fmt::Display;
use chrono::format::parse;
use crate::calculations::calculator::calculatorfunctions::{Calculator, has_enclosing_brackets, split_to_expressions};
use crate::calculations::calculator::solid::solid::{get_standard_methods, PrintableNumber, Solid, SolidNumber};
use crate::calculations::solids::realnumbers::RealNumbers;
pub struct ComplexNumbers{
}
pub struct ComplexNumber {
a : f64,
b : f64,
}
impl Solid<ComplexNumber> for ComplexNumbers{
fn get_solid_name() -> String {
return "Complex Numbers".to_string();
}
fn get_neutral_element_addition() -> ComplexNumber {
return ComplexNumber { a: 0.0, b: 0.0 };
}
fn add(x: ComplexNumber, y: ComplexNumber) -> ComplexNumber {
return ComplexNumber {a : x.a+y.a, b: x.b+y.b};
}
fn get_additive_inverse(x: ComplexNumber) -> ComplexNumber {
return ComplexNumber {a : -x.a, b: -x.b};
}
fn get_neutral_element_multiplicative() -> ComplexNumber {
return ComplexNumber{ a: 1.0, b: 0.0 }
}
fn multiply(x: ComplexNumber, y: ComplexNumber) -> ComplexNumber {
let a = x.a;
let b = x.b;
let c = y.a;
let d = y.b;
return ComplexNumber{
a : a * c - b * d,
b: a * d + c * b
};
}
fn get_multiplicative_inverse(x: ComplexNumber) -> ComplexNumber {
let nenner = (x.a.powi(2) + x.b.powi(2));
return ComplexNumber{a: x.a/ nenner,b: -(x.b/nenner)};
}
fn get_available_functions() -> Vec<(String, fn(Vec<String>) -> (ComplexNumber, String), Vec<i32>, i32)> {
return get_standard_methods::<ComplexNumber, ComplexNumbers>();
}
}
impl PrintableNumber for ComplexNumber {
fn to_sn_string(&self) -> String {
return format!("({},{})",self.a,self.b)
}
}
impl SolidNumber<ComplexNumber> for ComplexNumber {
fn is_number(s: &str) -> bool {
if !has_enclosing_brackets(&s.to_string()) {
if Calculator::<f64, RealNumbers>::parse(s).1==""{
return true;
}
if s.eq("i"){
return true;
}
return false;
}
else{
let numbers = split_to_expressions(&s.to_string(), vec![',']);
if numbers.0.len()!=2{
return false;
}
//println!("complex number: a={}, b={}", numbers.0[0], numbers.0[1]);
let a = Calculator::<f64, RealNumbers>::parse(numbers.0[0].as_str());
let b = Calculator::<f64, RealNumbers>::parse(numbers.0[1].as_str());
if (a.1!="") | (b.1!=""){
return false;
}
return true;
}
}
fn from_string(s: String) -> ComplexNumber {
if s.eq("i"){
return ComplexNumber{a: 0.0, b: 1.0};
}
let parsedFloat = Calculator::<f64, RealNumbers>::parse(s.as_str());
if parsedFloat.1==""{
return ComplexNumber{a : parsedFloat.0, b: 0.0};
}
let numbers = split_to_expressions(&s.to_string(), vec![',']);
let a = Calculator::<f64, RealNumbers>::parse(numbers.0[0].as_str());
let b = Calculator::<f64, RealNumbers>::parse(numbers.0[1].as_str());
return ComplexNumber {a: a.0, b: b.0 };
}
}Feel free to leave your opinion or questions in the comment section below.