use crate::{
Drain,
Global,
SmallVec
};
pub struct Splice<'a, I: Iterator + 'a, const N: usize> {
drain: Drain<'a, I::Item, N, Global>,
replace_with: I
}
impl<'a, I: Iterator + 'a, const N: usize> Splice<'a, I, N> {
pub(crate) fn new(drain: Drain<'a, I::Item, N, Global>, replace_with: I) -> Self {
Self {
drain,
replace_with
}
}
}
impl<'a, I, const N: usize> core::fmt::Debug for Splice<'a, I, N>
where
I: core::fmt::Debug + Iterator + 'a,
<I as Iterator>::Item: core::fmt::Debug
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("Splice").field(&self.drain).finish()
}
}
impl<I: Iterator, const N: usize> Iterator for Splice<'_, I, N> {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
self.drain.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.drain.size_hint()
}
}
impl<I: Iterator, const N: usize> DoubleEndedIterator for Splice<'_, I, N> {
fn next_back(&mut self) -> Option<Self::Item> {
self.drain.next_back()
}
}
impl<I: Iterator, const N: usize> ExactSizeIterator for Splice<'_, I, N> {}
impl<I: Iterator, const N: usize> Drop for Splice<'_, I, N> {
fn drop(&mut self) {
self.drain.by_ref().for_each(drop);
self.drain.iter = [].iter();
unsafe {
if self.drain.tail_len == 0 {
self.drain.vec.as_mut().extend(self.replace_with.by_ref());
return;
}
if !self.drain.fill(&mut self.replace_with) {
return;
}
let (lower_bound, _upper_bound) = self.replace_with.size_hint();
if lower_bound > 0 {
self.drain.move_tail(lower_bound);
if !self.drain.fill(&mut self.replace_with) {
return;
}
}
let mut collected = self
.replace_with
.by_ref()
.collect::<SmallVec<I::Item, N>>()
.into_iter();
if collected.len() > 0 {
self.drain.move_tail(collected.len());
let filled = self.drain.fill(&mut collected);
debug_assert!(filled);
debug_assert_eq!(collected.len(), 0);
}
}
}
}