use alloc::{vec, vec::Vec};
use core::{
fmt,
iter::FusedIterator,
slice::{Iter, IterMut},
};
use crate::Frame;
fn next<I: Iterator<Item = T>, T>(iter: &mut Vec<I>) -> Option<T> {
let out;
loop {
let last = iter.last_mut()?;
if let Some(next) = last.next() {
out = next;
break;
}
iter.pop();
}
Some(out)
}
#[must_use]
#[derive(Clone)]
pub struct Frames<'r> {
stack: Vec<Iter<'r, Frame>>,
}
impl<'r> Frames<'r> {
pub(crate) fn new(frames: &'r [Frame]) -> Self {
Self {
stack: vec![frames.iter()],
}
}
}
impl<'r> Iterator for Frames<'r> {
type Item = &'r Frame;
fn next(&mut self) -> Option<Self::Item> {
let frame = next(&mut self.stack)?;
self.stack.push(frame.sources().iter());
Some(frame)
}
}
impl FusedIterator for Frames<'_> {}
impl fmt::Debug for Frames<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
#[must_use]
pub struct FramesMut<'r> {
stack: Vec<IterMut<'r, Frame>>,
}
impl<'r> FramesMut<'r> {
pub(crate) fn new(frames: &'r mut [Frame]) -> Self {
Self {
stack: vec![frames.iter_mut()],
}
}
}
impl<'r> Iterator for FramesMut<'r> {
type Item = &'r mut Frame;
fn next(&mut self) -> Option<Self::Item> {
let frame = next(&mut self.stack)?;
let frame: *mut Frame = frame;
unsafe {
self.stack.push((*frame).sources_mut().iter_mut());
Some(&mut *frame)
}
}
}
impl FusedIterator for FramesMut<'_> {}