use crate::primitives::Peano;
use crate::primitives::{GetTail, Nibble, Present, Absent};
use crate::primitives::stream::{S, D0, StreamEq, DefaultMaxDepth};
use crate::primitives::nibble::{NibbleEq, *};
use super::node::{Empty, Leaf, Node16, EmptyNode16, Bucket};
use super::capability::Capability;
use super::evaluate::{EvalAt, Has};
pub trait InsertAt<Cap, Depth> {
type Out;
}
impl<Cap, Depth> InsertAt<Cap, Depth> for Empty {
type Out = Leaf<Cap>;
}
#[macros::node16]
impl<Cap, Depth, _Slots_> InsertAt<Cap, Depth> for _Node16_
where
Cap: Capability,
Depth: Peano,
Cap::Stream: GetTail<Depth>,
Self: NodeInsert<Cap, Depth, Cap::At<Depth>>,
{
type Out = <Self as NodeInsert<Cap, Depth, Cap::At<Depth>>>::Out;
}
pub trait NodeInsert<Cap, Depth, Nib: Nibble> {
type Out;
}
#[macros::node16(for_nibble_split)]
impl<Cap, Depth, _Slots_> NodeInsert<Cap, Depth, _Nibble_> for _Node16_
where
Cap: Capability,
Depth: Peano,
_SlotN_: InsertAt<Cap, S<Depth>>,
{
type Out = Node16<_Before_, <_SlotN_ as InsertAt<Cap, S<Depth>>>::Out, _After_>;
}
impl<NewCap, StoredCap, Depth> InsertAt<NewCap, Depth> for Leaf<StoredCap>
where
NewCap: Capability,
StoredCap: Capability,
Depth: Peano,
NewCap::Stream: GetTail<Depth>,
StoredCap::Stream: GetTail<Depth>,
Self: LeafInsert<NewCap, StoredCap, Depth, NewCap::At<Depth>, StoredCap::At<Depth>>,
{
type Out = <Self as LeafInsert<NewCap, StoredCap, Depth, NewCap::At<Depth>, StoredCap::At<Depth>>>::Out;
}
pub trait LeafInsert<NewCap, StoredCap, Depth, NewNib: Nibble, StoredNib: Nibble> {
type Out;
}
pub trait MakeNode16WithLeaf<Cap, Nib: Nibble> {
type Out;
}
pub trait MakeNode16WithTwoLeaves<NewCap, StoredCap, NewNib: Nibble, StoredNib: Nibble> {
type Out;
}
#[macros::node16(for_nibble_split)]
impl<Cap> MakeNode16WithLeaf<Cap, _Nibble_> for () {
type Out = Node16<_EmptyBefore_, Leaf<Cap>, _EmptyAfter_>;
}
pub trait LeafCollisionBranch<NewCap, StoredCap, IsCollision, Depth, Nib: Nibble> {
type Out;
}
impl<Cap, Depth, Nib> LeafCollisionBranch<Cap, Cap, Present, Depth, Nib> for Leaf<Cap>
where
Cap: Capability,
Nib: Nibble,
{
type Out = Leaf<Cap>; }
#[macros::node16(for_nibble_split)]
impl<NewCap, StoredCap, Depth> LeafCollisionBranch<NewCap, StoredCap, Absent, Depth, _Nibble_> for Leaf<StoredCap>
where
StoredCap: Capability,
NewCap: Capability,
Empty: InsertAt<StoredCap, S<Depth>>,
<Empty as InsertAt<StoredCap, S<Depth>>>::Out: InsertAt<NewCap, S<Depth>>,
{
type Out = Node16<
_EmptyBefore_,
<<Empty as InsertAt<StoredCap, S<Depth>>>::Out as InsertAt<NewCap, S<Depth>>>::Out,
_EmptyAfter_
>;
}
#[macros::node16(for_nibble_split)]
impl<NewCap, StoredCap, Depth> LeafInsert<NewCap, StoredCap, Depth, _Nibble_, _Nibble_> for Leaf<StoredCap>
where
NewCap: Capability,
StoredCap: Capability,
NewCap::Stream: StreamEq<StoredCap::Stream, DefaultMaxDepth>, Self: LeafCollisionBranch<
NewCap,
StoredCap,
<NewCap::Stream as StreamEq<StoredCap::Stream, DefaultMaxDepth>>::Out,
Depth,
_Nibble_
>,
{
type Out = <Self as LeafCollisionBranch<
NewCap,
StoredCap,
<NewCap::Stream as StreamEq<StoredCap::Stream, DefaultMaxDepth>>::Out,
Depth,
_Nibble_
>>::Out;
}
impl<NewCap, StoredCap, Depth, NewNib, StoredNib>
LeafInsert<NewCap, StoredCap, Depth, NewNib, StoredNib> for Leaf<StoredCap>
where
NewCap: Capability,
StoredCap: Capability,
NewNib: Nibble + NibbleEq<StoredNib, Out = Absent>,
StoredNib: Nibble,
EmptyNode16: NodeInsert<StoredCap, Depth, StoredNib>,
<EmptyNode16 as NodeInsert<StoredCap, Depth, StoredNib>>::Out:
NodeInsert<NewCap, Depth, NewNib>,
{
type Out = <<EmptyNode16 as NodeInsert<StoredCap, Depth, StoredNib>>::Out
as NodeInsert<NewCap, Depth, NewNib>>::Out;
}
pub trait RemoveAt<Cap, Depth> {
type Out;
}
impl<Cap, Depth> RemoveAt<Cap, Depth> for Empty {
type Out = Empty;
}
pub trait LeafRemove<IsMatch> {
type Out;
}
impl<S> LeafRemove<Present> for Leaf<S> {
type Out = Empty;
}
impl<S> LeafRemove<Absent> for Leaf<S> {
type Out = Leaf<S>;
}
impl<StoredCap, QCap, Depth> RemoveAt<QCap, Depth> for Leaf<StoredCap>
where
QCap: Capability,
StoredCap: Capability,
Leaf<StoredCap>: EvalAt<Has<QCap>, Depth>,
Leaf<StoredCap>: LeafRemove<<Leaf<StoredCap> as EvalAt<Has<QCap>, Depth>>::Out>,
{
type Out = <Leaf<StoredCap> as LeafRemove<<Leaf<StoredCap> as EvalAt<Has<QCap>, Depth>>::Out>>::Out;
}
pub trait NodeRemove<Cap, Depth, Nib: Nibble> {
type Out;
}
#[macros::node16(for_nibble_split)]
impl<Cap, Depth, _Slots_> NodeRemove<Cap, Depth, _Nibble_> for _Node16_
where
Cap: Capability,
_SlotN_: RemoveAt<Cap, S<Depth>>,
{
type Out = Node16<_Before_, <_SlotN_ as RemoveAt<Cap, S<Depth>>>::Out, _After_>;
}
#[macros::node16]
impl<Cap, Depth, _Slots_> RemoveAt<Cap, Depth> for _Node16_
where
Cap: Capability,
Depth: Peano,
Cap::Stream: GetTail<Depth>,
Self: NodeRemove<Cap, Depth, Cap::At<Depth>>,
{
type Out = <Self as NodeRemove<Cap, Depth, Cap::At<Depth>>>::Out;
}
impl<Cap, Tail, Depth> InsertAt<Cap, Depth> for Bucket<Cap, Tail>
where
Cap: Capability,
{
type Out = Self; }
impl<Cap, Tail, Depth> RemoveAt<Cap, Depth> for Bucket<Cap, Tail>
where
Cap: Capability,
{
type Out = Tail; }
#[diagnostic::on_unimplemented(
message = "Cannot add capability {Cap} to set {Self}",
label = "Failed to add {Cap} to {Self}",
note = "Ensure {Self} is a valid capability set (Empty/Leaf/Node) and {Cap} is a Capability."
)]
pub trait With<Cap>: Sized {
type Out;
}
impl<Ctx, Cap> With<Cap> for Ctx
where
Cap: Capability,
Ctx: InsertAt<Cap, D0>,
{
type Out = <Ctx as InsertAt<Cap, D0>>::Out;
}
pub trait Without<Cap>: Sized {
type Out;
}
impl<Ctx, Cap> Without<Cap> for Ctx
where
Cap: Capability,
Ctx: RemoveAt<Cap, D0>,
{
type Out = <Ctx as RemoveAt<Cap, D0>>::Out;
}