use alloc::vec::Vec;
use core::{iter::FusedIterator, marker::PhantomData};
use crate::{ReportRef, markers::Dynamic};
#[must_use]
pub struct ReportIter<'a, Ownership: 'static, ThreadSafety: 'static> {
stack: Vec<ReportRef<'a, Dynamic, Ownership, ThreadSafety>>,
_ownership: PhantomData<Ownership>,
_thread_safety: PhantomData<ThreadSafety>,
}
impl<'a, O, T> ReportIter<'a, O, T> {
pub(crate) fn from_raw(stack: Vec<ReportRef<'a, Dynamic, O, T>>) -> Self {
Self {
stack,
_ownership: PhantomData,
_thread_safety: PhantomData,
}
}
}
impl<'a, O, T> Iterator for ReportIter<'a, O, T> {
type Item = ReportRef<'a, Dynamic, O, T>;
fn next(&mut self) -> Option<Self::Item> {
let cur: ReportRef<'a, Dynamic, O, T> = self.stack.pop()?;
let new_children = cur
.children()
.iter()
.map(|child_report| {
unsafe {
ReportRef::<Dynamic, O, T>::from_cloneable(child_report)
}
})
.rev();
self.stack.extend(new_children);
Some(cur)
}
}
impl<'a, O, T> FusedIterator for ReportIter<'a, O, T> {}
impl<'a, O, T> Unpin for ReportIter<'a, O, T> {}
pub struct DowncastIterator<'a, D, Ownership: 'static, ThreadSafety: 'static> {
pub(crate) iter: ReportIter<'a, Ownership, ThreadSafety>,
pub(crate) _phantom: PhantomData<D>,
}
impl<'a, D: 'static, Ownership: 'static, ThreadSafety: 'static> Iterator
for DowncastIterator<'a, D, Ownership, ThreadSafety>
{
type Item = &'a D;
fn next(&mut self) -> Option<Self::Item> {
for report in self.iter.by_ref() {
let Some(report) = report.downcast_current_context() else {
continue;
};
return Some(report);
}
None
}
}
impl<'a, D: 'static, O, T> FusedIterator for DowncastIterator<'a, D, O, T> {}
impl<'a, D, O, T> Unpin for DowncastIterator<'a, D, O, T> {}