Reputation: 551
I am trying to read in a file until the end 2 bytes at a time and I want to catch the EOF error:
use byteorder::{BigEndian, ReadBytesExt}; // 1.3.4
use std::fs::File;
fn main() {
let filename = "/etc/hosts";
let mut file = File::open(filename).expect("Cannot open file");
loop {
let binary = match file.read_u16::<BigEndian>() {
Ok(binary) => binary,
Err(e) => panic!("Can't read from file: {}, err {}", filename, e),
// Can I catch the EOF error here?
};
println!("{:?}", binary);
}
}
Upvotes: 44
Views: 22133
Reputation: 1162
I find...
Err(e) => match e.kind() {
EndOfFile => break,
SomeOtherError => do_something(),
_ => panic!("Can't read from file: {}, err {}", filename, e),
},
... to be more readable than...
Ok(binary) => binary,
Err(ref e) if e.kind() == EndOfFile => break,
Err(ref e) if e.kind() == SomeOtherError => do_something(),
Err(e) => panic!("Can't read from file: {}, err {}", filename, e),
(I'm not sure what other errors we could expect to get...)
In other situations where the match guards might not be the same - the way that we're repeating e.kind()
- we couldn't use the nested match
.
This works as of Rust 1.25.
Upvotes: 15
Reputation: 104120
This works in Rust version 1.17.0 (and probably back to Rust 1.0):
let binary = match file.read_u16::<BigEndian>() {
Err(ref e) if e.kind() == std::io::ErrorKind::UnexpectedEof => break,
Err(e) => panic!("Can't read from file: {}, err {}", filename, e),
Ok(binary) => binary,
};
Upvotes: 31
Reputation: 90912
Editor's note: This code example is from a version of Rust prior to 1.0 and does not apply to stable Rust 1.0
io::Error
. The concept of nested pattern matching still applies in other contexts.
You can match the kind as part of the pattern, using some more advanced features of pattern matching:
Err(IoError { kind: IoErrorKind::EndOfFile, .. }) => break,
Err(e) => panic!("Can't read from file: {}, err {}", filename, e),
The first variant means “an Err
containing an IoError
where kind
is IoErrorKind::EndOfFile
and all the other fields are whatever you like”. The second then means “any other Err
, binding the contained value to the variable name e
”.
Upvotes: 8
Reputation: 27005
Here is an example of matching a MySQL IoError
:
match pool.prep_exec("SELECT SLEEP(10)", ()) {
Ok(_) => (),
Err(mysql::Error::IoError(e)) => {
eprintln!("IoError: {}", e);
do_something();
}
Err(e) => {
eprintln!("{}", e);
return;
}
}
Upvotes: 2
Reputation: 551
I figured it out. I changed this line to check the error type! Hope this helps others.
Err(e) => if e.kind == IoErrorKind::EndOfFile { break } else { panic!("Can't read from file: {}, err {}", filename, e) },
Upvotes: 0