pipecircuit 0.0.25

Correct. Robust. Fast. Portable. Pick four.
Documentation
use super::super::{BulkSelection, BulkUpdateError, BulkUpdateWorkspace, WarpTableRow};
use super::{CallerQuery, CallerSelection, CallerStorage, CallerWarpTable, CallerWarpTableColumns};
use crate::storage::query_workspace::{
    QueryChunkStorage, QueryScratchStorage, QueryWorkspaceError,
};

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CallerBulkUpdateError<Selection> {
    QueryStorage(QueryWorkspaceError),
    Selection(Selection),
    DifferentTables,
    Update(BulkUpdateError),
}

#[doc(hidden)]
pub trait CallerWarpTableBulkUpdate<Row: WarpTableRow, Update, Output>:
    CallerWarpTableColumns<Row>
{
    fn bulk_update(
        &mut self,
        indexes: &mut Self::Indexes,
        selection: BulkSelection<'_>,
        update: Update,
    ) -> Result<Output, BulkUpdateError>;
}

impl<'storage, Row: WarpTableRow, Columns: CallerWarpTableColumns<Row>, Brand>
    CallerWarpTable<'storage, Row, Columns, Brand>
{
    pub fn bulk_update_in<Chunks, Scratch, Pending, Group, Slots, Update, Output, Error>(
        &mut self,
        workspace: &mut BulkUpdateWorkspace<Chunks, Scratch, Pending, Group, Slots>,
        select: impl for<'table, 'workspace> FnOnce(
            CallerQuery<'table, 'workspace, Row, Brand, CallerStorage<'storage, Row, Columns>>,
        ) -> Result<
            CallerSelection<'table, 'workspace, Row, Brand, CallerStorage<'storage, Row, Columns>>,
            Error,
        >,
        update: Update,
    ) -> Result<Output, CallerBulkUpdateError<Error>>
    where
        Chunks: QueryChunkStorage,
        Scratch: QueryScratchStorage,
        Pending: QueryScratchStorage,
        Group: QueryScratchStorage,
        Slots: AsMut<[u16]>,
        Columns: CallerWarpTableBulkUpdate<Row, Update, Output>,
    {
        let selected = select(
            self.query_in(
                workspace
                    .query
                    .membership()
                    .map_err(CallerBulkUpdateError::QueryStorage)?,
            ),
        )
        .map_err(CallerBulkUpdateError::Selection)?;
        if !core::ptr::eq(self, selected.table) {
            return Err(CallerBulkUpdateError::DifferentTables);
        }
        let membership = selected.into_workspace();
        Columns::bulk_update(
            &mut self.columns,
            &mut self.indexes,
            BulkSelection {
                selected: &membership,
                pending: workspace.pending.as_mut(),
                group: workspace.group.as_mut(),
                slots: workspace.slots.as_mut(),
            },
            update,
        )
        .map_err(CallerBulkUpdateError::Update)
    }
}