I'm building a chained future
ActorFuture<Item = Vec<String>, Error = Vec<String>, Actor = Self>
On success it will have vector of string outputs of all futures chained with .and_then
. On first error processing will stop, and I want to return succeeded futures outputs and final (failed) future error. I want to use same vector to handle both paths: ok and err. But the compiler complains:
242 | .map(|o| {v.push(o); v})
| --- value moved (into closure) here
243 | .map_err(|e| {v.push(format!("{}", e)); v})
| ^ value captured here after move
Why is that? Is it possible to go both in map
and map_err
at once? This should never happen in my understanding.
An example:
#[test]
fn test_map_and_map_err() {
let mut v = Vec::new();
Ok("foo".to_string())
.map(|i| { v.push(i); v })
.map_err(|e: String| { v.push(e); v });
}
error[E0382]: capture of moved value: `v`
--> src/lib.rs:6:32
|
5 | .map(|i| { v.push(i); v })
| --- value moved (into closure) here
6 | .map_err(|e: String| { v.push(e); v });
| ^ value captured here after move
|
= note: move occurs because `v` has type `std::vec::Vec<std::string::String>`, which does not implement the `Copy` trait
The compiler doesn't know that the closures passed to
map
andmap_err
are mutually exclusive. Even if it did, it has no way of constructing two closures that both own the same value.You need to use a construct that is "transparent" to the compiler, like
match
:Or you can swap the value out instead: