pipecircuit 0.0.25

Correct. Robust. Fast. Portable. Pick four.
Documentation
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::ops::DerefMut;

use super::{
    WarpTableRow, WarpTableRowGetError, WarpTableRowGetOutcome, WarpTableRowReplaceError,
    WarpTableRowReplaceOutcome,
};

pub enum AllocatedStorage {}

pub trait WarpTableBacking<Row: WarpTableRow> {
    type Indexes: super::WarpTableIndexes<Row>;
    type Mut<'row>
    where
        Self: 'row,
        Row: 'row;
    type Ids;
    type Columns;
    type Buckets: DerefMut<Target = [u32]>;

    fn ids(ids: &Self::Ids) -> &[Row::Id];
    fn append_id(ids: &mut Self::Ids, id: Row::Id);
    fn remove_id(ids: &mut Self::Ids, row: usize);
    fn columns_mut(columns: &mut Self::Columns) -> Row::ColumnsMut<'_>;
    fn append(columns: &mut Self::Columns, row: Row);
    fn swap_remove(columns: &mut Self::Columns, row: usize) -> Row;
    fn get<'row>(
        id: &'row Row::Id,
        columns: &'row Self::Columns,
        row: usize,
    ) -> Result<WarpTableRowGetOutcome<Row::Ref<'row>>, WarpTableRowGetError>
    where
        Row: 'row;
    fn rows<'row>(
        ids: &'row [Row::Id],
        columns: &'row Self::Columns,
    ) -> Result<Row::Rows<'row>, WarpTableRowGetError>
    where
        Row: 'row;

    fn fold_rows<'row, Acc, Fold>(
        ids: &'row [Row::Id],
        columns: &'row Self::Columns,
        start: usize,
        initial: Acc,
        mut fold: Fold,
    ) -> Result<Acc, WarpTableRowGetError>
    where
        Row: 'row,
        Fold: FnMut(Acc, Row::Ref<'row>) -> Acc,
    {
        ids.iter()
            .enumerate()
            .try_fold(initial, |acc, (offset, id)| {
                let WarpTableRowGetOutcome::Present { row } =
                    Self::get(id, columns, start.saturating_add(offset))?;
                Ok(fold(acc, row))
            })
    }

    fn get_mut<'row>(
        id: &'row Row::Id,
        columns: &'row mut Self::Columns,
        indexes: &'row mut Self::Indexes,
        row: usize,
    ) -> Result<WarpTableRowGetOutcome<Self::Mut<'row>>, WarpTableRowGetError>
    where
        Row: 'row,
        Self: 'row;
    fn replace(
        columns: &mut Self::Columns,
        row: usize,
        replacement: Row,
    ) -> Result<WarpTableRowReplaceOutcome<Row>, WarpTableRowReplaceError<Row>>;
}

#[cfg(feature = "alloc")]
impl<Row: WarpTableRow> WarpTableBacking<Row> for AllocatedStorage {
    type Indexes = super::indexes::AllocatedIndexes<Row>;
    type Mut<'row>
        = Row::Mut<'row>
    where
        Row: 'row;
    type Ids = Vec<Row::Id>;
    type Columns = Row::Columns;
    type Buckets = Vec<u32>;

    fn ids(ids: &Self::Ids) -> &[Row::Id] {
        ids
    }

    fn append_id(ids: &mut Self::Ids, id: Row::Id) {
        ids.push(id);
    }

    fn remove_id(ids: &mut Self::Ids, row: usize) {
        ids.swap_remove(row);
    }

    fn columns_mut(columns: &mut Self::Columns) -> Row::ColumnsMut<'_> {
        Row::columns_mut(columns)
    }

    fn append(columns: &mut Self::Columns, row: Row) {
        Row::append(columns, row);
    }

    fn swap_remove(columns: &mut Self::Columns, row: usize) -> Row {
        Row::swap_remove(columns, row)
    }

    fn get<'row>(
        id: &'row Row::Id,
        columns: &'row Self::Columns,
        row: usize,
    ) -> Result<WarpTableRowGetOutcome<Row::Ref<'row>>, WarpTableRowGetError>
    where
        Row: 'row,
    {
        Row::get(id, columns, row)
    }

    fn rows<'row>(
        ids: &'row [Row::Id],
        columns: &'row Self::Columns,
    ) -> Result<Row::Rows<'row>, WarpTableRowGetError>
    where
        Row: 'row,
    {
        Row::rows(ids, columns)
    }

    fn fold_rows<'row, Acc, Fold>(
        ids: &'row [Row::Id],
        columns: &'row Self::Columns,
        start: usize,
        initial: Acc,
        fold: Fold,
    ) -> Result<Acc, WarpTableRowGetError>
    where
        Row: 'row,
        Fold: FnMut(Acc, Row::Ref<'row>) -> Acc,
    {
        Row::fold_rows(ids, columns, start, initial, fold)
    }

    fn get_mut<'row>(
        id: &'row Row::Id,
        columns: &'row mut Self::Columns,
        indexes: &'row mut Self::Indexes,
        row: usize,
    ) -> Result<WarpTableRowGetOutcome<Row::Mut<'row>>, WarpTableRowGetError>
    where
        Row: 'row,
    {
        Row::get_mut(id, columns, indexes, row)
    }

    fn replace(
        columns: &mut Self::Columns,
        row: usize,
        replacement: Row,
    ) -> Result<WarpTableRowReplaceOutcome<Row>, WarpTableRowReplaceError<Row>> {
        Row::replace(columns, row, replacement)
    }
}