I am trying to read in a file until the end 2 bytes at a time. I want to catch the EOF error. I have this code:
loop {
let binary = match file.read_be_u16() {
Ok(binary) => binary,
Err(e) => panic!("Can't read from file: {}, err {}", filename, e),
// Can I catch this EOF error here?
};
println!("{:?}", binary);
}
At least rustc version rustc 1.17.0 (56124baa9 2017-04-24) doesn't allow destructuring the Err
that Chris Morgan's answer used. I found this to work:
Err(ref e) if e.kind() == std::io::ErrorKind::NotFound => true,
Err(e) => { println!("{:?}", e); false }
Ok(_) => false,
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
”.
Being new to Rust I'm not really too aware of the "Rusty" way to do things (so not sure if this would be discouraged) but I personally find...
Ok(binary) => binary,
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),
(Not sure what other errors we could expect to get...)
Obviously, 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
Note:
Works as of rustc 1.25.0 (84203cac6 2018-03-25)
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) },
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;
}
}