Retrieving error from Result<T, Err(e)>

Hi Folks,
I am new to Rust and am trying to figure out Result return types. I am trying to extract the error code returned by fn read_username_from_file -> Result<String, io::Error>. The compiler reports that the Result type is not indexed. If someone could point me in to a solution, I would appreciate it.

Thanks

use std::fs::File;
use std::io;
use std::io::Read;

fn main() {
      println!("{}", read_username_from_file()[1]);
}

fn read_username_from_file() -> Result<String, io::Error> {
    let f = File::open("hello.txt");
    let mut f = match f {
        Ok(file) => file,
        Err(e) => return Err(e),
    };

    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}```

Or should be in the Help forum?

Please read our post on syntax highlighting: Forum Code Formatting and Syntax Highlighting

Then edit your post to follow our guidelines. (don't post a new post, but edit it)

Done. Thanks Alice

To crash your program in case of failure, use unwrap.

fn main() {
    println!("{}", read_username_from_file().unwrap());
}

To crash your program in case of success, use unwrap_err.

fn main() {
    println!("{}", read_username_from_file().unwrap_err());
}

You can also print the Result directly.

fn main() {
    println!("{:?}", read_username_from_file());
}

or you can match to do different things in each case:

fn main() {
    match read_username_from_file() {
        Ok(file) => { ... },
        Err(err) => println!("{}", err),
    }
}

otherwise if main returns a Result, you can use the question mark operator to return it on failure:

fn main() -> Result<(), io::Error> {
    println!("{}", read_username_from_file()?);
    
    Ok(())
}

Note that the question mark could also be used inside read_username_from_file.

// this
let f = File::open("hello.txt");
let mut f = match f {
    Ok(file) => file,
    Err(e) => return Err(e),
};

// becomes this
let mut f = File::open("hello.txt")?;
4 Likes

I have seen the ? operator but haven't read about it yet. I shall investigate!. Thanks Alice.

You don't use indexing to access the variants of an enum, you need to write a match statement.

All of @alice's solutions reduce to a match on the Ok and Err variants, the compiler may write this match for you (like in the case of ?), or it could be hidden inside a method (like unwrap()).

2 Likes

This. :top: An enum is a type that contains exactly one of its many possible variants at a time. It is thus not possible to ask an enum to return an arbitrary variant – you first have to make sure that it is that particular variant.

If enums supported this kind of "indexing", they would be identical to tuples. The very point of an enum is that it's not a "hold this AND that" type. It's a "hold this OR that" type instead.

3 Likes