Reputation: 1205
Sorry for naming this a so ambiguous title, but I can't come up with a better one.
The read_dir()
method defined in std::fs
returns instances of io::Result<DirEntry>
, which is the alias of Result<DirEntry, io::Error>
. When the caller does not exist on file system, it returns the error.
Now my code is
dir_a.read_dir();
dir_b.read_dir();
dir_c.read_dir();
And dir_a
, dir_b
, dir_c
all may not exist. So these three statements may return the same io::Error
, but for my program, dir_a
, dir_b
and dir_c
have different meaning, where I want to handle the error for each one respectively.
So I defined my own enum MyError
as
enum MyError {
Dir_a_not_exist,
Dir_b_not_exist,
Dir_c_not_exist,
}
How can I transform the same io::Error
to my different three MyError
?
My ugly way is to
match dir_a.read_dir() {
Ok => match dir_b.read_dir() {
Ok => match dir_c.read_dir() {
Ok => { /* do something */ },
Err => return MyError::Dir_c_not_exist,
},
Err => return MyError::Dir_b_not_exist,
},
Err => return MyError::Dir_a_not_exist,
};
Is there any graceful way I can handle this?
Upvotes: 0
Views: 226
Reputation: 103761
Result
has a function called or
, that allows you to forward the result if it's Ok, or transform it if it's an error. With that, you can do something like this:
fn foo(dir_a: &Path, dir_b: &Path, dir_c: &Path) -> Result<(), MyError> {
dir_a.read_dir().or(Err(MyError::DirAnotExist))?;
dir_b.read_dir().or(Err(MyError::DirBnotExist))?;
dir_c.read_dir().or(Err(MyError::DirCnotExist))?;
/* do something */
Ok(())
}
Upvotes: 4