Collecting a vector of results into a result of vectors

I know it's possible to turn a vector with type Vec<Result<T, ()>> into a Result<Vec, ()>. But I haven't found a way to do it the other way round, that is turn a Vec<Result<(), T>> into a Result<(), Vec>.

In my case, I'm writing a collision function for a physics engine. You supply a function with a slice of objects that it might collide with, it runs a simulation, and returns either a blank Ok(()), or an error with a boxed slice of items it collided with. I can do this:

    let results1: Vec<Result<usize, ()>> = vec![
        Ok(0),
        Ok(1),
        Ok(2),
        Err(()),
    ];

    let result1 = results1.clone().into_iter()
        .collect::<Result<Vec<_>, ()>>();

But this won't compile:

    let results2: Vec<Result<(), usize>> = vec![
        Ok(()),
        Ok(()),
        Ok(()),
        Err(3),
        Err(3),
    ];

    let result2 = results2.clone().into_iter()
        .collect::<Result<(), Vec<_>>>();

Is it that conversion just not implemented, or am I missing something?

1 Like

https://doc.rust-lang.org/stable/std/iter/trait.FromIterator.html#implementors

It seems such conversions are not implemented.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7a1cd841170aac6df850368ca0b71407

You can use Result::err() to make Err into Some and Ok into None, and then use Iterator::filter_map() to get only Some values.

However, I think it would be better to create dedicated enum to represent possible collision, rather than using Result.
By defining your own types, it would be easy to implement traits such as FromIterator.

Thanks!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.