use alloc::vec::Vec;
use core::{cmp::Ord, fmt::Debug};
use crate::{interval::Interval, node::Node};
#[derive(PartialEq, Eq, Debug)]
pub struct Entry<'a, T: Ord, V> {
value: &'a V,
interval: &'a Interval<T>,
}
impl<'a, T: Ord + 'a, V: 'a> Entry<'a, T, V> {
#[must_use]
pub fn value(&self) -> &'a V {
self.value
}
#[must_use]
pub fn interval(&self) -> &'a Interval<T> {
self.interval
}
}
#[derive(Debug)]
pub struct IntervalTreeIterator<'v, 'i, T: Ord, V> {
pub(crate) nodes: Vec<&'v Node<T, V>>,
pub(crate) interval: &'i Interval<T>,
}
impl<'v, 'i, T: Ord + 'i, V: 'v> Iterator for IntervalTreeIterator<'v, 'i, T, V> {
type Item = Entry<'v, T, V>;
fn next(&mut self) -> Option<Entry<'v, T, V>> {
loop {
let node_ref = match self.nodes.pop() {
None => return None,
Some(node) => node,
};
if node_ref.right_child.is_some() {
self.nodes.push(node_ref.right_child.as_ref().unwrap());
}
if node_ref.left_child.is_some()
&& Node::<T, V>::is_ge(
&node_ref.left_child.as_ref().unwrap().get_max(),
&self.interval.get_low(),
)
{
self.nodes.push(node_ref.left_child.as_ref().unwrap());
}
if Interval::overlaps(node_ref.interval(), self.interval) {
return Some(Entry {
value: node_ref.value(),
interval: node_ref.interval(),
});
}
}
}
}
#[derive(PartialEq, Eq, Debug)]
pub struct EntryMut<'a, T: Ord, V> {
value: &'a mut V,
interval: &'a Interval<T>,
}
impl<'a, T: Ord + 'a, V: 'a> EntryMut<'a, T, V> {
pub fn value(&'a mut self) -> &'a mut V {
self.value
}
#[must_use]
pub fn interval(&self) -> &'a Interval<T> {
self.interval
}
}
#[derive(Debug)]
pub struct IntervalTreeIteratorMut<'v, 'i, T: Ord, V> {
pub(crate) nodes: Vec<&'v mut Node<T, V>>,
pub(crate) interval: &'i Interval<T>,
}
impl<'v, 'i, T: Ord + 'i, V: 'v> Iterator for IntervalTreeIteratorMut<'v, 'i, T, V> {
type Item = EntryMut<'v, T, V>;
fn next(&mut self) -> Option<EntryMut<'v, T, V>> {
loop {
let node_ref = match self.nodes.pop() {
None => return None,
Some(node) => node,
};
let overlaps = Interval::overlaps(node_ref.interval(), self.interval);
if node_ref.right_child.is_some() {
self.nodes.push(node_ref.right_child.as_mut().unwrap());
}
if node_ref.left_child.is_some()
&& Node::<T, V>::is_ge(
&node_ref.left_child.as_ref().unwrap().get_max(),
&self.interval.get_low(),
)
{
self.nodes.push(node_ref.left_child.as_mut().unwrap());
}
if overlaps {
return Some(EntryMut {
value: node_ref.value.as_mut().unwrap(),
interval: node_ref.interval.as_ref().unwrap(),
});
}
}
}
}