There are a couple of problems here:
fn glob_abs_path(fpath: &str) -> std::result::Result<Vec<PathBuf>, Error> {
Ok(glob(fpath)?.map(|val| val.unwrap()).collect::<Vec<_>>())
}
At the end of glob_abs_path, you are collecting the value into a Vec. If you try to use the ? operator on a vec, it will fail:
error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
--> src/lib.rs:26:8
|
26 | Ok(glob(fpath)?.map(|val| val.unwrap()).collect::<Vec<_>>()?)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied
to type `std::vec::Vec<std::result::Result<std::path::PathBuf, glob::GlobError>>`
The ? operator can only be applied to values that implement std::ops::Try, namely Result<_, _>. So what we have to do is collect the iterator into a Result:
fn glob_abs_path(fpath: &str) -> std::result::Result<Vec<PathBuf>, Error> {
Ok(glob(fpath)?.map(|val| val.unwrap()).collect::<std::result::Result<Vec<_>, _>>()?)
}
However, we get another error here:
error[E0277]: a value of type `std::result::Result<std::vec::Vec<_>, _>` cannot be built
from an iterator over elements of type `std::path::PathBuf`
--> src/lib.rs:26:43
|
26 | Ok(glob(fpath)?.map(|val| val.unwrap()).collect::<std::result::Result<Vec<_>, _>>())
| ^^^^^^^ value of type
| `std::result::Result<std::vec::Vec<_>, _>` cannot be built from
| `std::iter::Iterator<Item=std::path::PathBuf>`
|
The issue here is that we are unwrapping the value .map(|val| val.unwrap()) before collecting it, and the iterator does not know how to convert the unwrapped value (PathBuf ) to a Result. Removing the call to unwrap fixes the issue:
fn glob_abs_path(fpath: &str) -> std::result::Result<Vec<PathBuf>, Error> {
Ok(glob(fpath)?.collect::<std::result::Result<Vec<_>, _>>()?)
}
The code now compiles. You mentioned that you had a type alias for Result:
type MyResult<T> = std::result::Result<T, Error>
You can use this type alias in the return value:
fn glob_abs_path(fpath: &str) -> MyResult<Vec<PathBuf>> {
Ok(glob(fpath)?.collect::<std::result::Result<Vec<_>, _>>()?)
}
However, when you use it in to collect the iterator:
fn glob_abs_path(fpath: &str) -> MyResult<Vec<PathBuf>> {
Ok(glob(fpath)?.collect::<MyResult<Vec<_>>>()?)
}
It fails:
error[E0277]: a value of type `std::result::Result<std::vec::Vec<_>, Error>`
cannot be built from an iterator over elements of type `std::result::Result<std::path::PathBuf, glob::GlobError>`
--> src/lib.rs:26:21
|
26 | Ok(glob(fpath)?.collect::<MyResult<Vec<_>>>()?)
| ^^^^^^^ value of type `std::result::Result<std::vec::Vec<_>, Error>`
| cannot be built from `std::iter::Iterator<Item=std::result::Result<std::path::PathBuf, glob::GlobError>>`
|
This is because MyResult explicitly states the return value as your custom Error type. Iterator cannot convert GlobError to your Error. That conversion is handled by the ? operator:
fn glob_abs_path(fpath: &str) -> MyResult<Vec<PathBuf>> {
Ok(glob(fpath)?.collect::<std::result::Result<Vec<_>, GlobError>>()?)
}
As you can see above, the iterator is collected into <std::result::Result<Vec<_>, GlobError>, and then converted into std::result::Result<Vec<_>, YourError> (MyResult) by the ? operator.
Here is the final working code as a Rust Playground