Error handling inputing a part of a vec that doesn't exist

Viewed 31

My code is this:

use std::io;
use std::cmp::Ordering;
use rand::Rng;
use owo_colors::{OwoColorize, colors::{CustomColor}};
pub fn main() {
    println!("{}", "Please Guess (1-5)".magenta());
    let random = rand::thread_rng().gen_range(1..=5);
    let mut choices = vec![1,2,3,4,5];
  
    loop {
        let mut guess = String::new();
        io::stdin().read_line(&mut guess).expect("Failed to read line");    
        let guess: usize = match guess.trim().parse() {
            Ok(number) => number,
            Err(error) => { println!("{}", error); 
            continue 
            }
        };
        
        let index = choices.iter().position(|x| *x == guess).unwrap();
        choices.remove(index);
        if guess != random {
        println!("{}",
        format!("You haven't picked {:?}", choices.fg::<CustomColor<255, 110, 110>>()));
        }


    match guess.cmp(&random) {
        Ordering::Less => println!("Too small!"),
        Ordering::Greater => println!("Too big!"),
        Ordering::Equal => { 
            println!("{}", "You win!".blue().bold());
            break; }
        };
        
    }
}

And after entering a number it gets deleted. Then after entering it again it gives me an error:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src\main.rs:20:62
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\hello_world.exe` (exit code: 101)

I've tried doing a match statement like this:

        match index {
            Ok(number)=> number,
            Err(e)=> {
                println!("There has been an error!",e);  
             }
        }

but I'm getting this error

mismatched types
expected type `usize`
   found enum `Result<_, _>`rustcE0308

How do I properly error handle this?

1 Answers

When writing

let index = choices.iter().position(|x| *x == guess).unwrap();

You are telling it to find the position of the element which equals the guessed number. But what if the number didn't exist? Generally speaking, calling expect or unwrap on Result or Option types are the places where applications will break. You'll have to check these types for their content before working with their prospective values.

It might seem cumbersome at first but this is one of the big plusses of Rust: you are pushed into dealing with errors and if you do, you'll have some rock-solid applications.

Also, if you're new to Rust, you might want to look at https://doc.rust-lang.org/rust-by-example/std/result/question_mark.html - it really helps working with Results and passing errors up the call chain, converting them as required.

Related