I wrote (the one I think neat) piece of code, but I can't compile, because take is consuming elements iterator, instead of borrowing it.
let mut layer_sizes = Vec::new();
let mut layer_size = 1;
let mut elements = source.iter().chain(std::iter::repeat(&None));
while layer_size > 0{
layer_sizes.push(layer_size);
layer_size = *(&mut elements.take(layer_size).filter(|x| x.is_some()).count()) * 2;
}
I wanted to 'take N elements from iterator' in a loop. I thought take is a perfect match for that, but it's not. Either I miss something here (which I do, I suppose), or it's less useful than I hoped.
It's useful as a consuming method, too. For example, if you want the first N items of an iterator and ignore the rest, then .take(N) is what you want as-is.
In fact, this is a more typical use case than "take and then continue iterating over the original iterator".
One pitfall of the non-consuming case is that if the (&mut iter).take(n) iterator is not run to completion, then less than n elements are removed from the original iterator.
Another important design decision here is that while a consuming .take(n) method can be applied to the non-consuming case (by passing a mutable reference to an iterator), the reverse is not true. You cannot obtain an owned iterator only returning the first n items of some other iterator, if you only have a &mut self version of .take(n) (unless you start working with some third-party crate solution to create self-referencing data structures).