use core::{
fmt,
ops::Range,
};
use super::{
IntervalMap, Interval,
ix::{IndexType, DefaultIx},
};
pub struct VacantEntry<'a, T, V, Ix: IndexType = DefaultIx> {
tree: &'a mut IntervalMap<T, V, Ix>,
parent: Ix,
left_side: bool,
interval: Interval<T>,
}
impl<'a, T, V, Ix: IndexType> VacantEntry<'a, T, V, Ix>
where T: Copy,
{
pub(super) fn new(tree: &'a mut IntervalMap<T, V, Ix>, parent: Ix, left_side: bool, interval: Interval<T>) -> Self {
Self { tree, parent, left_side, interval }
}
pub fn interval(&self) -> Range<T> {
self.interval.to_range()
}
}
impl<'a, T, V, Ix: IndexType> VacantEntry<'a, T, V, Ix>
where T: Copy + PartialOrd,
{
pub fn insert(self, value: V) -> &'a mut V {
self.tree.insert_at(self.parent, self.left_side, self.interval, value)
}
}
impl<'a, T, V, Ix: IndexType> fmt::Debug for VacantEntry<'a, T, V, Ix>
where T: PartialOrd + Copy + fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "VacantEntry({:?})", self.interval.to_range())
}
}
pub struct OccupiedEntry<'a, T, V, Ix: IndexType = DefaultIx> {
tree: &'a mut IntervalMap<T, V, Ix>,
index: Ix,
}
impl<'a, T, V, Ix: IndexType> OccupiedEntry<'a, T, V, Ix>
where T: Copy,
{
pub(super) fn new(tree: &'a mut IntervalMap<T, V, Ix>, index: Ix) -> Self {
Self { tree, index }
}
pub fn interval(&self) -> Range<T> {
self.tree.nodes[self.index.get()].interval.to_range()
}
pub fn get(&self) -> &V {
&self.tree.nodes[self.index.get()].value
}
pub fn get_mut(&mut self) -> &mut V {
&mut self.tree.nodes[self.index.get()].value
}
pub fn into_mut(self) -> &'a mut V {
&mut self.tree.nodes[self.index.get()].value
}
pub fn insert(&mut self, value: V) -> V {
core::mem::replace(&mut self.tree.nodes[self.index.get()].value, value)
}
}
impl<'a, T, V, Ix: IndexType> fmt::Debug for OccupiedEntry<'a, T, V, Ix>
where T: PartialOrd + Copy + fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let node = &self.tree.nodes[self.index.get()];
write!(f, "OccupiedEntry({:?} => {:?})", node.interval.to_range(), node.value)
}
}
impl<'a, T, V, Ix: IndexType> OccupiedEntry<'a, T, V, Ix>
where T: Copy + PartialOrd,
{
pub fn remove(self) -> V {
self.tree.remove_at(self.index).expect("Cannot be None")
}
}
pub enum Entry<'a, T, V, Ix: IndexType = DefaultIx> {
Vacant(VacantEntry<'a, T, V, Ix>),
Occupied(OccupiedEntry<'a, T, V, Ix>)
}
impl<'a, T, V, Ix: IndexType> Entry<'a, T, V, Ix>
where T: Copy,
{
pub fn interval(&self) -> Range<T> {
match self {
Entry::Occupied(entry) => entry.interval(),
Entry::Vacant(entry) => entry.interval(),
}
}
}
impl<'a, T, V, Ix: IndexType> Entry<'a, T, V, Ix>
where T: Copy + PartialOrd,
{
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default),
}
}
pub fn or_insert_with<F>(self, default: F) -> &'a mut V
where F: FnOnce() -> V,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default()),
}
}
pub fn or_insert_with_interval<F>(self, default: F) -> &'a mut V
where F: FnOnce(Range<T>) -> V,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let val = default(entry.interval());
entry.insert(val)
}
}
}
pub fn and_modify<F>(self, f: F) -> Self
where F: FnOnce(&mut V),
{
match self {
Entry::Occupied(mut entry) => {
f(entry.get_mut());
Entry::Occupied(entry)
}
Entry::Vacant(entry) => Entry::Vacant(entry),
}
}
}
impl<'a, T, V, Ix: IndexType> Entry<'a, T, V, Ix>
where T: Copy + PartialOrd,
V: Default,
{
pub fn or_default(self) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(V::default()),
}
}
}
impl<'a, T, V, Ix: IndexType> fmt::Debug for Entry<'a, T, V, Ix>
where T: PartialOrd + Copy + fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Entry::Occupied(entry) => entry.fmt(f),
Entry::Vacant(entry) => entry.fmt(f),
}
}
}