use super::{AllocItem, Down, InternalNodeRef, Key, Next, NodeRef};
use crate::options::{LeafSize, ListOptions};
use core::ops::{AddAssign, Deref, SubAssign};
use core::ptr::NonNull;
pub unsafe trait LeafRef: Clone {
type Options: ListOptions;
fn next(&self) -> Option<LeafNext<Self>>;
fn set_next(this: This<&'_ Self>, next: Option<LeafNext<Self>>);
fn size(&self) -> LeafSize<Self> {
Default::default()
}
}
#[derive(Clone, Debug)]
pub enum LeafNext<L: LeafRef> {
Leaf(L),
Data(NonNull<AllocItem<L>>),
}
pub struct This<T>(T);
impl<T> Deref for This<&'_ T> {
type Target = T;
fn deref(&self) -> &T {
self.0
}
}
impl<L: LeafRef> NodeRef for L {
type Leaf = L;
fn next(&self) -> Option<Next<Self>> {
LeafRef::next(self).map(|next| match next {
LeafNext::Leaf(node) => Next::Sibling(node),
LeafNext::Data(data) => {
Next::Parent(unsafe { InternalNodeRef::from_ptr(data) })
}
})
}
fn set_next(&self, next: Option<Next<Self>>) {
LeafRef::set_next(
This(self),
next.map(|next| match next {
Next::Sibling(node) => LeafNext::Leaf(node),
Next::Parent(node) => LeafNext::Data(node.as_ptr()),
}),
);
}
fn size(&self) -> LeafSize<Self> {
LeafRef::size(self)
}
fn as_down(&self) -> Down<Self> {
Down::Leaf(self.clone())
}
fn from_down(down: Down<Self>) -> Option<Self> {
match down {
Down::Leaf(node) => Some(node),
_ => None,
}
}
fn key(&self) -> Option<Key<Self>> {
use crate::options::StoreKeysPriv;
super::StoreKeys::<Self>::as_key(self)
}
}
pub trait LeafExt: LeafRef {
fn set_next_leaf(&self, next: Option<LeafNext<Self>>) {
Self::set_next(This(self), next);
}
}
impl<L: LeafRef> LeafExt for L {}
pub trait SizeExt: AddAssign + SubAssign + Sized {
fn add(mut self, other: Self) -> Self {
self += other;
self
}
fn sub(mut self, other: Self) -> Self {
self -= other;
self
}
}
impl<T: AddAssign + SubAssign> SizeExt for T {}