layer-rs 0.1.1

Effect-TS like type level DI container in Rust, with O(log n) get and insert
Documentation
use super::*;

/// This requires that the target requirement does not already exist in the tree.
pub trait Insert<NewReq, MinDepth, Queries, Next>
where
    MinDepth: IsNumber,
    Self::MinDepth: IsNumber,
{
    /// Inserts a new requirement into the tree.
    /// If you want to replace an existing requirement, `remove` it beforehand.
    fn insert(self, new_req: NewReq) -> Next;
    type MinDepth;
    type Queries;
}

// insert: insert into leaf node
impl<Req, NewReq> Insert<NewReq, Succ<Zero>, Left<Here>, Node<Req, Node<NewReq, (), ()>, ()>>
    for Node<Req, (), ()>
{
    fn insert(self, new_req: NewReq) -> Node<Req, Node<NewReq, (), ()>, ()> {
        Node {
            requirement: self.requirement,
            prev_left: Node {
                requirement: new_req,
                prev_left: (),
                prev_right: (),
            },
            prev_right: (),
        }
    }

    type MinDepth = Succ<Zero>;
    type Queries = Left<Here>;
}

// insert: insert into left-null tree
impl<Req, ReqR, NewReq>
    Insert<
        NewReq,
        Succ<Succ<Zero>>,
        Left<Right<Here>>,
        Node<Req, Node<NewReq, (), ()>, Node<ReqR, (), ()>>,
    > for Node<Req, (), Node<ReqR, (), ()>>
{
    fn insert(self, new_req: NewReq) -> Node<Req, Node<NewReq, (), ()>, Node<ReqR, (), ()>> {
        Node {
            requirement: self.requirement,
            prev_left: Node {
                requirement: new_req,
                prev_left: (),
                prev_right: (),
            },
            prev_right: self.prev_right,
        }
    }

    type MinDepth = Succ<Succ<Zero>>;
    type Queries = Left<Here>;
}

// insert: insert into right-null tree
impl<Req, ReqL, NewReq>
    Insert<
        NewReq,
        Succ<Succ<Zero>>,
        Right<Left<Here>>,
        Node<Req, Node<ReqL, (), ()>, Node<NewReq, (), ()>>,
    > for Node<Req, Node<ReqL, (), ()>, ()>
{
    fn insert(self, new_req: NewReq) -> Node<Req, Node<ReqL, (), ()>, Node<NewReq, (), ()>> {
        Node {
            requirement: self.requirement,
            prev_left: self.prev_left,
            prev_right: Node {
                requirement: new_req,
                prev_left: (),
                prev_right: (),
            },
        }
    }

    type MinDepth = Succ<Succ<Zero>>;
    type Queries = Right<Here>;
}

// insert: recurse into left subtree twice
impl<
    Req,
    ReqL,
    SubtreeLL,
    SubtreeLR,
    ReqR,
    SubtreeRL,
    SubtreeRR,
    NewReq,
    NextSubtreeL,
    PrevQueriesL,
>
    Insert<
        NewReq,
        <Node<Req, NextSubtreeL, Node<ReqR, SubtreeRL, SubtreeRR>> as MinDepth>::Output,
        Left<PrevQueriesL>,
        Node<Req, NextSubtreeL, Node<ReqR, SubtreeRL, SubtreeRR>>,
    > for Node<Req, Node<ReqL, SubtreeLL, SubtreeLR>, Node<ReqR, SubtreeRL, SubtreeRR>>
where
    Node<ReqL, SubtreeLL, SubtreeLR>: MinDepth,
    Node<ReqR, SubtreeRL, SubtreeRR>: MinDepth,
    Node<Req, NextSubtreeL, Node<ReqR, SubtreeRL, SubtreeRR>>: MinDepth,
    NextSubtreeL: MinDepth,
    Node<ReqL, SubtreeLL, SubtreeLR>:
        Insert<NewReq, <NextSubtreeL as MinDepth>::Output, PrevQueriesL, NextSubtreeL>,
    (): LessThan<
            <Node<ReqL, SubtreeLL, SubtreeLR> as MinDepth>::Output,
            <Node<ReqR, SubtreeRL, SubtreeRR> as MinDepth>::Output,
        >,
{
    fn insert(self, new_req: NewReq) -> Node<Req, NextSubtreeL, Node<ReqR, SubtreeRL, SubtreeRR>> {
        Node {
            requirement: self.requirement,
            prev_left: self.prev_left.insert(new_req),
            prev_right: self.prev_right,
        }
    }

    type MinDepth =
        Succ<<Node<Req, NextSubtreeL, Node<ReqR, SubtreeRL, SubtreeRR>> as MinDepth>::Output>;
    type Queries = Left<PrevQueriesL>;
}

// insert: recurse into left subtree twice
impl<
    Req,
    ReqL,
    SubtreeLL,
    SubtreeLR,
    ReqR,
    SubtreeRL,
    SubtreeRR,
    NewReq,
    NextSubtreeR,
    PrevQueriesR,
>
    Insert<
        NewReq,
        <Node<Req, Node<ReqL, SubtreeLL, SubtreeLR>, NextSubtreeR> as MinDepth>::Output,
        Right<PrevQueriesR>,
        Node<Req, Node<ReqL, SubtreeLL, SubtreeLR>, NextSubtreeR>,
    > for Node<Req, Node<ReqL, SubtreeLL, SubtreeLR>, Node<ReqR, SubtreeRL, SubtreeRR>>
where
    Node<ReqL, SubtreeLL, SubtreeLR>: MinDepth,
    Node<ReqR, SubtreeRL, SubtreeRR>: MinDepth,
    Node<Req, Node<ReqL, SubtreeLL, SubtreeLR>, NextSubtreeR>: MinDepth,
    NextSubtreeR: MinDepth,
    Node<ReqR, SubtreeRL, SubtreeRR>:
        Insert<NewReq, <NextSubtreeR as MinDepth>::Output, PrevQueriesR, NextSubtreeR>,
    (): GreaterThanOrEqual<
            <Node<ReqL, SubtreeLL, SubtreeLR> as MinDepth>::Output,
            <Node<ReqR, SubtreeRL, SubtreeRR> as MinDepth>::Output,
        >,
{
    fn insert(self, new_req: NewReq) -> Node<Req, Node<ReqL, SubtreeLL, SubtreeLR>, NextSubtreeR> {
        Node {
            requirement: self.requirement,
            prev_left: self.prev_left,
            prev_right: self.prev_right.insert(new_req),
        }
    }

    type MinDepth =
        Succ<<Node<Req, Node<ReqL, SubtreeLL, SubtreeLR>, NextSubtreeR> as MinDepth>::Output>;
    type Queries = Right<PrevQueriesR>;
}