I wrote another iterator adapter similar to the one in
https://users.rust-lang.org/t/feedback-for-iterator-adapter/98090/9
This one works like intersperse
but lets SomeIterator<IntoIteratorA<U>>
be interspersed with IntoIteratorB<U>
to get an Iterator<Box<dyn Iterator<U>>
. You can then call .flatten()
to get an Iterator<U>
.
I have a question, but feedback is also welcome.
Prompted by my last topic, I tried which bounds I could leave away. For some of them I was quite astonished that I could just leave them away.
For example I commented out a line S: Clone
on IterExt::intersperse_with_iter()
. Why is that possible? The Iterator
implementation for IntersperseWithIter<I, S>
clearly has the trait bound S: Clone
. Or would that just mean that IntersperseWithIter<I, S>
just isn't an iterator when chained on an Iterator<IntoIterator>
where the IntoIterator
isn't Clone
?. How should I then proceed? Leave the bounds on or not?
use std::iter::Peekable;
struct IntersperseWithIter<I, S>
where
I: Iterator,
I::Item: IntoIterator<Item = S::Item>,
S: IntoIterator,
{
separator: S,
iter: Peekable<I>,
needs_sep: bool,
}
impl<I, S> Iterator for IntersperseWithIter<I, S>
where
I: Iterator,
I::Item: IntoIterator<Item = S::Item> + 'static,
S: IntoIterator + Clone + 'static,
{
type Item = Box<(dyn Iterator<Item = S::Item>)>;
fn next(&mut self) -> Option<Self::Item> {
if self.needs_sep && self.iter.peek().is_some() {
self.needs_sep = false;
Some(Box::new(self.separator.clone().into_iter()))
} else {
self.needs_sep = true;
self.iter
.next()
.map(|x| Box::new(x.into_iter()) as Self::Item)
}
}
}
trait IterExt: Iterator {
fn intersperse_with_iter<S>(self, separator: S) -> IntersperseWithIter<Self, S>
where
Self: Sized,
Self::Item: IntoIterator<Item = S::Item>,
S: IntoIterator,
// S: Clone,
{
IntersperseWithIter {
separator,
iter: self.peekable(),
needs_sep: false,
}
}
}
impl<I> IterExt for I where
I: Iterator
// I::Item: IntoIterator,
// <I::Item as IntoIterator>::Item: Clone,
{
}
fn main() {
let a: [&[u8]; 3] = [b"hello", b"my", b"world"];
let b: Vec<_> = a
.into_iter()
.intersperse_with_iter(b" SEP ")
.flatten()
.cloned()
.collect();
println!("{:?}", String::from_utf8(b).unwrap());
}
Output:
"hello SEP my SEP world"
Errors:
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.94s
Running `target/debug/playground`