pipecircuit 0.0.10

Correct. Robust. Fast. Portable.
Documentation
use super::{Selection, SelectionRows};
use crate::storage::warp_table::secondary_index::RangeIndexMembership;
use crate::storage::warp_table::{RangeIndexBounds, WarpTable, WarpTableRow};

#[must_use]
pub enum RangeIndexLookupOutcome<'table, Row: WarpTableRow, Brand, Key> {
    Present {
        bounds: RangeIndexBounds<Key>,
        selection: Selection<'table, Row, Brand>,
    },
    Absent {
        bounds: RangeIndexBounds<Key>,
        selection: Selection<'table, Row, Brand>,
    },
}

impl<'table, Row: WarpTableRow, Brand, Key> RangeIndexLookupOutcome<'table, Row, Brand, Key> {
    pub fn len(&self) -> u64 {
        self.selection().len()
    }

    pub fn is_empty(&self) -> bool {
        self.selection().is_empty()
    }

    pub fn rows(self) -> SelectionRows<'table, Row, Brand>
    where
        Row::Indexes: super::rows::StableSlotResolver,
    {
        self.into_selection().rows()
    }

    pub(super) const fn selection(&self) -> &Selection<'table, Row, Brand> {
        match self {
            Self::Present { selection, .. } | Self::Absent { selection, .. } => selection,
        }
    }

    pub(super) fn into_selection(self) -> Selection<'table, Row, Brand> {
        match self {
            Self::Present { selection, .. } | Self::Absent { selection, .. } => selection,
        }
    }
}

impl<'table, Row: WarpTableRow, Brand, Key> From<RangeIndexLookupOutcome<'table, Row, Brand, Key>>
    for Selection<'table, Row, Brand>
{
    fn from(outcome: RangeIndexLookupOutcome<'table, Row, Brand, Key>) -> Self {
        outcome.into_selection()
    }
}

#[doc(hidden)]
pub fn bind_range_lookup<'table, Row, Brand, Key>(
    table: &'table WarpTable<Row, Brand>,
    membership: RangeIndexMembership<Key>,
) -> RangeIndexLookupOutcome<'table, Row, Brand, Key>
where
    Row: WarpTableRow,
{
    let (bounds, slots) = membership.into_parts();
    match slots {
        Some(slots) => RangeIndexLookupOutcome::Present {
            bounds,
            selection: Selection::owned(table, slots),
        },
        None => RangeIndexLookupOutcome::Absent {
            bounds,
            selection: Selection::empty(table),
        },
    }
}