Hey everyeone,
a reddit user complained about collecting an iterator into an array is very cumbersome. I agreed.
That's why I wrote some little code, like this:
#![feature(maybe_uninit_array_assume_init)]
#![feature(maybe_uninit_uninit_array)]
use std::mem::MaybeUninit;
#[derive(Debug, PartialEq)]
enum Code {
TooFew,
TooMany,
}
trait CollectArray: Iterator {
fn try_collect<const N: usize>(self) -> Result<[Self::Item; N], Code>
where
Self: Sized,
{
let mut result = MaybeUninit::uninit_array();
let mut max_idx = 0;
for i in self {
if max_idx >= N {
return Err(Code::TooMany);
}
result[max_idx] = MaybeUninit::new(i);
max_idx += 1;
}
if max_idx < N {
return Err(Code::TooFew);
}
Ok(unsafe { MaybeUninit::array_assume_init(result) })
}
}
impl<I: Iterator> CollectArray for I {}
fn main() {
let a = std::iter::repeat(3).try_collect::<5>();
assert_eq!(a, Err(Code::TooMany));
let b = std::iter::repeat(3).take(4).try_collect::<5>();
assert_eq!(b, Err(Code::TooFew));
let c = std::iter::repeat(3).take(5).try_collect::<5>();
assert_eq!(c, Ok([3, 3, 3, 3, 3]));
}
Miri says it's safe.
I see at least one problem, where the elements won't get dropped, if an error occurs.
Can somebody help me with this?
Maybe I'd like to publish a crate and my big dream is, that this is in std at some time.
Feedback is more than welcome.