Logo

My Journey with Rust: Building a Command-Line Calculator

October 31, 2024
11 min read
0 views
My Journey with Rust: Building a Command-Line Calculator

My Rust Adventure: Building a Command-Line Calculator

Hey there, fellow code enthusiasts! It's Harshit here, and today I'm super excited to share my journey into the world of Rust. If you're anything like me - a high school student juggling studies, coding passions, and a million other things - you're probably wondering, "Why Rust?" Well, buckle up, because we're about to find out together!

Rolling green hills representing the learning journey

Our Rust Expedition: What's in Store?

Here's a sneak peek of our coding adventure:

Project Setup

Setting up our Rust project (easier than setting up for board exams, I promise!)

Basic Input/Output

Learning to talk to our program (no social skills required)

Implementing Operations

Adding math operations (finally, a use for all that algebra)

Error Handling

Making our calculator foolproof (or at least Harshit-proof)

Testing

Ensuring our calculator works (unlike my science experiments)

Base Camp: Project Setup

Let's kick things off by creating our Rust project:

cargo new rust_calculator
cd rust_calculator

This sets up a new directory with all the Rust essentials. It's like packing your backpack for a coding expedition!

"Harshit, organizing your code is like organizing your room. Do it right, and you'll always find what you need. Do it wrong, and... well, you've seen your room."

My CS Teacher

The Heart of Our Calculator

Now, let's write the core of our calculator. Don't worry if it looks intimidating - we'll break it down!

use std::io::{self, Write};

fn main() {
    println!("Welcome to Harshit's Rust Calculator!");
    println!("Enter an expression (e.g., 2 + 3) or 'quit' to exit:");
    
    loop {
        print!("> ");
        io::stdout().flush().unwrap();
        
        let mut input = String::new();
        io::stdin()
            .read_line(&mut input)
            .expect("Failed to read line");
            
        if input.trim() == "quit" {
            println!("Thanks for calculating with me!");
            break;
        }
        
        match calculate_result(&input) {
            Ok(result) => println!("Result: {}", result),
            Err(e) => println!("Oops! {}", e),
        }
    }
}

The Brain of Our Calculator

Now for the real magic - the calculation function:

fn calculate_result(input: &str) -> Result<f64, String> {
    let parts: Vec<&str> = input.trim().split_whitespace().collect();
    
    if parts.len() != 3 {
        return Err("Whoa there! I need exactly three parts: number, operator, number.".to_string());
    }
    
    let num1: f64 = parts[0].parse().map_err(|_| "First number looks sus. Try again?")?;
    let operator = parts[1];
    let num2: f64 = parts[2].parse().map_err(|_| "Second number is not cooperating. Another shot?")?;
    
    match operator {
        "+" => Ok(num1 + num2),
        "-" => Ok(num1 - num2),
        "*" => Ok(num1 * num2),
        "/" => {
            if num2 == 0.0 {
                Err("Division by zero! Even Rust can't handle that level of rebel.".to_string())
            } else {
                Ok(num1 / num2)
            }
        }
        _ => Err("Unknown operator. Stick to +, -, *, or / for now!".to_string()),
    }
}

Rust Concepts That Blew My Mind

  1. Ownership and Borrowing: Rust's way of managing memory. It's like lending your favorite pen - you know exactly who has it and when you'll get it back.
  2. Error Handling: Using Result<T, E> is like having a safety net while doing acrobatics. It's saved me from many runtime crashes!
  3. Pattern Matching: The match expression is like a Swiss Army knife for control flow. So versatile!
  4. Type Safety: Rust's compiler is like that one friend who always catches your mistakes before they become embarrassing. Annoying sometimes, but you're grateful in the end.

"I never thought I'd say this, but I'm starting to love the Rust compiler. It's like having a really strict but helpful coding buddy."

Me, at 2 AM, debugging

Let's Test This Bad Boy

Time to make sure our calculator isn't just a pretty face:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_addition() {
        assert_eq!(calculate_result("2 + 2").unwrap(), 4.0);
    }

    #[test]
    fn test_division_by_zero() {
        assert!(calculate_result("5 / 0").is_err());
    }

    #[test]
    fn test_invalid_input() {
        assert!(calculate_result("1 + + 2").is_err());
    }
}

Level Up Your Calculator

Now that we've got the basics down, here are some cool ways to take it to the next level:

  1. Add more operations (like power or modulus - impress your math teacher!)
  2. Implement parentheses support (because BODMAS is life)
  3. Add memory functions (store and recall results - handy for long calculations)
  4. Play with floating-point precision (because sometimes you need more than two decimal places)

Wrapping Up

Wow, we've come a long way! We've built a working calculator and learned some key Rust concepts along the way. Here's what we covered:

  • Setting up a Rust project (easier than I thought!)
  • Basic Rust syntax (once you get used to the semicolons, it's not so bad)
  • Handling user input and output (talking to your program is fun!)
  • Error handling with Result (because errors happen, even to the best of us)
  • Pattern matching with match (it's like a supercharged if-else)
  • Testing (because even geniuses double-check their work)

Remember, learning Rust is a journey. There will be times when you feel like banging your head against the wall (looking at you, borrow checker!), but trust me, it gets better. The concepts that seem tough now will become second nature before you know it.

"Harshit, learning a new skill is like building muscle. It might hurt at first, but that's how you know you're growing."

Not My Dad

Ready to dive deeper? Check out the Rust Book - it's like the Harry Potter series of programming, but with more semicolons and fewer wizards.

Keep coding, keep learning, and remember - every error message is just a stepping stone to becoming a better programmer. Until next time, this is Harshit, signing off. Stay curious, stay persistent, and may the Rust be with you! 🦀💻