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);
}
}
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,
};
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
”.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With