A Compound Interest Calculator in Rust

This is a small command-line program written in Rust as an exercise in the language’s basics: reading from standard input, parsing strings into numeric types, and performing floating-point arithmetic. The program prompts the user for four inputs — a principal amount, an annual interest rate expressed as a percentage, a compounding frequency (number of times per year), and a time horizon in years — then applies the standard compound interest formula A = P (1 + r/n)nt to compute the final balance. It prints both the total amount and the interest earned, formatted to two decimal places.

The updated version refactors input handling into a dedicated read_number helper that loops until the user provides a valid, non-negative number — using a match on the parse result rather than panicking on bad input. It also flushes stdout explicitly before reading so the prompt appears on the same line as the cursor, and formats the output as a structured summary panel. The core formula is unchanged. Start by defining the repo with cargo new interest-calculator and then copy and paste the following code in the src/main.rs file:

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

fn main() {
    // Print a clean UI Header
    println!("=============================================");
    println!("       📊 COMPOUND INTEREST CALCULATOR       ");
    println!("=============================================");
    println!(" Welcome! Please provide the details below.\n");

    // 1. Get Principal with Error Handling
    let principal = read_number("💰 Enter the principal amount ($): ");

    // 2. Get Annual Rate
    let rate = read_number("📈 Enter the annual interest rate (%): ");
    let r = rate / 100.0; // Convert percentage to decimal

    // 3. Get Compounding Frequency
    let n = read_number("🔄 Enter times compounded per year (e.g., 12 for monthly): ");

    // 4. Get Time in years
    let t = read_number("⏳ Enter the number of years: ");

    // 5. Calculations
    let total_amount = principal * (1.0 + r / n).powf(n * t);
    let interest_earned = total_amount - principal;

    // 6. Print a Nice Summary UI
    println!("\n=============================================");
    println!("                📋 RESULTS                   ");
    println!("=============================================");
    println!(" Initial Principal:  ${:<10.2}", principal);
    println!(" Interest Rate:      {:.2}%", rate);
    println!(" Years Invested:     {:.1} years", t);
    println!("---------------------------------------------");
    println!(" ✨ Total Balance:   ${:<10.2}", total_amount);
    println!(" 💸 Interest Earned: ${:<10.2}", interest_earned);
    println!("=============================================\n");
}

/// Helper function to read and validate user input.
/// It will loop infinitely until the user types a valid, positive number.
fn read_number(prompt: &str) -> f64 {
    loop {
        // Print the prompt on the same line
        print!("{}", prompt);
        io::stdout().flush().unwrap(); // Force Rust to show the prompt immediately

        let mut input = String::new();
        if io::stdin().read_line(&mut input).is_err() {
            println!("❌ Error reading input. Please try again.");
            continue;
        }

        // Error Handling using Match
        match input.trim().parse::<f64>() {
            Ok(num) if num >= 0.0 => return num, // Valid positive number! Exit loop and return it.
            Ok(_) => println!("⚠️  Please enter a positive number."),
            Err(_) => println!("❌ Invalid input. Please enter a valid number (e.g., 1500 or 4.5)."),
        }
        println!(); // Add a blank line for spacing before retrying
    }
}