graphrecords-query 0.5.0

High-performance graph-based data records
Documentation
use super::{DynIndex, DynIndexRef, DynValue};
use crate::{
    Arity, Bare, BoxedIterator, Definite, ElementShape, Indexed, Mask, Multiple, Ordered,
    QueryResult, Single, Unit, Unordered,
};

pub enum DynArityStream<'a, T: 'a> {
    MultipleOrdered(BoxedIterator<'a, T>),
    MultipleUnordered(BoxedIterator<'a, T>),
    Single(Option<T>),
    Definite(T),
}

pub enum DynStream<'a> {
    IndexedValue(DynArityStream<'a, (DynIndexRef<'a>, QueryResult<DynValue>)>),
    IndexedMask(DynArityStream<'a, (DynIndexRef<'a>, QueryResult<bool>)>),
    IndexedUnit(DynArityStream<'a, (DynIndexRef<'a>, QueryResult<()>)>),
    BareValue(DynArityStream<'a, QueryResult<DynValue>>),
    BareMask(DynArityStream<'a, QueryResult<bool>>),
}

pub trait DynArity: Arity {
    fn erase<'a, T: 'a>(container: Self::Container<'a, T>) -> DynArityStream<'a, T>;

    fn project<'a, T: 'a>(stream: DynArityStream<'a, T>) -> Self::Container<'a, T>;
}

impl DynArity for Multiple<Ordered> {
    fn erase<'a, T: 'a>(container: Self::Container<'a, T>) -> DynArityStream<'a, T> {
        DynArityStream::MultipleOrdered(container)
    }

    fn project<'a, T: 'a>(stream: DynArityStream<'a, T>) -> Self::Container<'a, T> {
        let DynArityStream::MultipleOrdered(container) = stream else {
            panic!("registry selected an ordered-multiple lane for a different dynamic arity")
        };
        container
    }
}

impl DynArity for Multiple<Unordered> {
    fn erase<'a, T: 'a>(container: Self::Container<'a, T>) -> DynArityStream<'a, T> {
        DynArityStream::MultipleUnordered(container)
    }

    fn project<'a, T: 'a>(stream: DynArityStream<'a, T>) -> Self::Container<'a, T> {
        let DynArityStream::MultipleUnordered(container) = stream else {
            panic!("registry selected an unordered-multiple lane for a different dynamic arity")
        };
        container
    }
}

impl DynArity for Single {
    fn erase<'a, T: 'a>(container: Self::Container<'a, T>) -> DynArityStream<'a, T> {
        DynArityStream::Single(container)
    }

    fn project<'a, T: 'a>(stream: DynArityStream<'a, T>) -> Self::Container<'a, T> {
        let DynArityStream::Single(container) = stream else {
            panic!("registry selected a single lane for a different dynamic arity")
        };
        container
    }
}

impl DynArity for Definite {
    fn erase<'a, T: 'a>(container: Self::Container<'a, T>) -> DynArityStream<'a, T> {
        DynArityStream::Definite(container)
    }

    fn project<'a, T: 'a>(stream: DynArityStream<'a, T>) -> Self::Container<'a, T> {
        let DynArityStream::Definite(container) = stream else {
            panic!("registry selected a definite lane for a different dynamic arity")
        };
        container
    }
}

pub trait DynStreamShape: ElementShape {
    fn erase<'a, C: DynArity>(container: C::Container<'a, Self::Element<'a>>) -> DynStream<'a>
    where
        Self: 'a;

    fn project<'a, C: DynArity>(stream: DynStream<'a>) -> C::Container<'a, Self::Element<'a>>
    where
        Self: 'a;
}

impl DynStreamShape for Indexed<DynIndex, DynValue> {
    fn erase<'a, C: DynArity>(container: C::Container<'a, Self::Element<'a>>) -> DynStream<'a>
    where
        Self: 'a,
    {
        DynStream::IndexedValue(C::erase(container))
    }

    fn project<'a, C: DynArity>(stream: DynStream<'a>) -> C::Container<'a, Self::Element<'a>>
    where
        Self: 'a,
    {
        let DynStream::IndexedValue(stream) = stream else {
            panic!("registry selected an indexed dynamic-value lane for a different dynamic shape")
        };
        C::project(stream)
    }
}

impl DynStreamShape for Indexed<DynIndex, Mask> {
    fn erase<'a, C: DynArity>(container: C::Container<'a, Self::Element<'a>>) -> DynStream<'a>
    where
        Self: 'a,
    {
        DynStream::IndexedMask(C::erase(container))
    }

    fn project<'a, C: DynArity>(stream: DynStream<'a>) -> C::Container<'a, Self::Element<'a>>
    where
        Self: 'a,
    {
        let DynStream::IndexedMask(stream) = stream else {
            panic!("registry selected an indexed mask lane for a different dynamic shape")
        };
        C::project(stream)
    }
}

impl DynStreamShape for Indexed<DynIndex, Unit> {
    fn erase<'a, C: DynArity>(container: C::Container<'a, Self::Element<'a>>) -> DynStream<'a>
    where
        Self: 'a,
    {
        DynStream::IndexedUnit(C::erase(container))
    }

    fn project<'a, C: DynArity>(stream: DynStream<'a>) -> C::Container<'a, Self::Element<'a>>
    where
        Self: 'a,
    {
        let DynStream::IndexedUnit(stream) = stream else {
            panic!("registry selected an indexed unit lane for a different dynamic shape")
        };
        C::project(stream)
    }
}

impl DynStreamShape for Bare<DynValue> {
    fn erase<'a, C: DynArity>(container: C::Container<'a, Self::Element<'a>>) -> DynStream<'a>
    where
        Self: 'a,
    {
        DynStream::BareValue(C::erase(container))
    }

    fn project<'a, C: DynArity>(stream: DynStream<'a>) -> C::Container<'a, Self::Element<'a>>
    where
        Self: 'a,
    {
        let DynStream::BareValue(stream) = stream else {
            panic!("registry selected a bare dynamic-value lane for a different dynamic shape")
        };
        C::project(stream)
    }
}

impl DynStreamShape for Bare<Mask> {
    fn erase<'a, C: DynArity>(container: C::Container<'a, Self::Element<'a>>) -> DynStream<'a>
    where
        Self: 'a,
    {
        DynStream::BareMask(C::erase(container))
    }

    fn project<'a, C: DynArity>(stream: DynStream<'a>) -> C::Container<'a, Self::Element<'a>>
    where
        Self: 'a,
    {
        let DynStream::BareMask(stream) = stream else {
            panic!("registry selected a bare mask lane for a different dynamic shape")
        };
        C::project(stream)
    }
}