The Guessing Loop

Random numbers, stdin, and match — the smallest complete Rust program.

Part 1 of 3Updated

Every Rust tutorial starts here for a reason: it exercises loop, match, parsing, and the rand crate in about thirty lines.

Add the dependency

cargo add rand

The loop

use rand::Rng;
use std::io::{self, Write};
use std::cmp::Ordering;

fn main() {
    let secret = rand::rng().random_range(1..=100);

    loop {
        print!("guess: ");
        io::stdout().flush().unwrap();

        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();

        let Ok(guess) = input.trim().parse::<u32>() else {
            println!("that's not a number");
            continue;
        };

        match guess.cmp(&secret) {
            Ordering::Less => println!("too small"),
            Ordering::Greater => println!("too big"),
            Ordering::Equal => {
                println!("got it!");
                break;
            }
        }
    }
}

The match on Ordering is exhaustive — remove one arm and the compiler rejects the program. That exhaustiveness is the single most useful property of Rust’s enums.

io::stdout().flush() is needed because print! (no newline) leaves the prompt buffered.