pipecircuit 0.0.25

Correct. Robust. Fast. Portable. Pick four.
Documentation
use super::WarpTableRow;

pub trait WarpTableIndexes<Row: WarpTableRow>: Sized {
    type IndexesInsertError: core::fmt::Debug;
    type PreparedIndexesInsert<'indexes>
    where
        Self: 'indexes,
        Row: 'indexes;
    type IndexesRemoveError: core::fmt::Debug;
    type PreparedIndexesRemove<'indexes>
    where
        Self: 'indexes,
        Row: 'indexes;
    type IndexesReplaceError: core::fmt::Debug;
    type PreparedIndexesReplace<'indexes>
    where
        Self: 'indexes,
        Row: 'indexes;
    fn unique_insert_conflict(indexes: &Self, row: &Row) -> Option<Row::UniqueConflict>;
    fn unique_replace_conflict<'row>(
        indexes: &Self,
        current: Row::Ref<'row>,
        replacement: &Row,
    ) -> Option<Row::UniqueConflict>
    where
        Row: 'row;

    /// Validates and reserves every index change without publishing any of it.
    ///
    /// Returning an error or dropping the prepared value must leave `indexes`
    /// unchanged. A successful preparation must make its commit infallible.
    fn try_prepare_indexes_insert<'indexes>(
        indexes: &'indexes mut Self,
        row: &Row,
    ) -> Result<Self::PreparedIndexesInsert<'indexes>, Self::IndexesInsertError>
    where
        Self: 'indexes,
        Row: 'indexes;

    /// Publishes exactly one previously prepared index insertion.
    fn commit_indexes_insert<'indexes>(prepared: Self::PreparedIndexesInsert<'indexes>)
    where
        Self: 'indexes,
        Row: 'indexes;

    /// Validates every index removal without publishing any of it.
    ///
    /// The supplied row reference is the logical row at `index`. Dropping the
    /// prepared value must leave all indexes unchanged.
    fn try_prepare_indexes_remove<'indexes, 'row>(
        indexes: &'indexes mut Self,
        row: Row::Ref<'row>,
        index: usize,
    ) -> Result<Self::PreparedIndexesRemove<'indexes>, Self::IndexesRemoveError>
    where
        Self: 'indexes,
        Row: 'indexes + 'row;

    /// Publishes exactly one previously prepared index removal.
    fn commit_indexes_remove<'indexes>(prepared: Self::PreparedIndexesRemove<'indexes>)
    where
        Self: 'indexes,
        Row: 'indexes;

    /// Validates every index move required by a row replacement.
    ///
    /// Dropping the prepared value must restore the indexes to their original
    /// observable state. A successful preparation makes commit infallible.
    fn try_prepare_indexes_replace<'indexes, 'row>(
        indexes: &'indexes mut Self,
        current: Row::Ref<'row>,
        replacement: &Row,
        index: usize,
    ) -> Result<Self::PreparedIndexesReplace<'indexes>, Self::IndexesReplaceError>
    where
        Self: 'indexes,
        Row: 'indexes + 'row;

    /// Publishes exactly one previously prepared set of index moves.
    fn commit_indexes_replace<'indexes>(prepared: Self::PreparedIndexesReplace<'indexes>)
    where
        Self: 'indexes,
        Row: 'indexes;
}

#[cfg(feature = "alloc")]
pub struct AllocatedIndexes<Row: WarpTableRow>(pub Row::Indexes);

#[cfg(feature = "alloc")]
impl<Row: WarpTableRow> core::ops::Deref for AllocatedIndexes<Row> {
    type Target = Row::Indexes;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

#[cfg(feature = "alloc")]
impl<Row: WarpTableRow> core::ops::DerefMut for AllocatedIndexes<Row> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

#[cfg(feature = "alloc")]
impl<Row: WarpTableRow> WarpTableIndexes<Row> for AllocatedIndexes<Row> {
    type IndexesInsertError = Row::IndexesInsertError;
    type IndexesRemoveError = Row::IndexesRemoveError;
    type IndexesReplaceError = Row::IndexesReplaceError;
    type PreparedIndexesInsert<'indexes>
        = Row::PreparedIndexesInsert<'indexes>
    where
        Self: 'indexes,
        Row: 'indexes;
    type PreparedIndexesRemove<'indexes>
        = Row::PreparedIndexesRemove<'indexes>
    where
        Self: 'indexes,
        Row: 'indexes;
    type PreparedIndexesReplace<'indexes>
        = Row::PreparedIndexesReplace<'indexes>
    where
        Self: 'indexes,
        Row: 'indexes;
    fn unique_insert_conflict(indexes: &Self, row: &Row) -> Option<Row::UniqueConflict> {
        Row::unique_insert_conflict(&indexes.0, row)
    }
    fn unique_replace_conflict<'row>(
        indexes: &Self,
        current: Row::Ref<'row>,
        replacement: &Row,
    ) -> Option<Row::UniqueConflict>
    where
        Row: 'row,
    {
        Row::unique_replace_conflict(&indexes.0, current, replacement)
    }
    fn try_prepare_indexes_insert<'indexes>(
        indexes: &'indexes mut Self,
        row: &Row,
    ) -> Result<Self::PreparedIndexesInsert<'indexes>, Self::IndexesInsertError>
    where
        Self: 'indexes,
        Row: 'indexes,
    {
        Row::try_prepare_indexes_insert(&mut indexes.0, row)
    }
    fn commit_indexes_insert<'indexes>(prepared: Self::PreparedIndexesInsert<'indexes>)
    where
        Self: 'indexes,
        Row: 'indexes,
    {
        Row::commit_indexes_insert(prepared)
    }
    fn try_prepare_indexes_remove<'indexes, 'row>(
        indexes: &'indexes mut Self,
        row: Row::Ref<'row>,
        index: usize,
    ) -> Result<Self::PreparedIndexesRemove<'indexes>, Self::IndexesRemoveError>
    where
        Self: 'indexes,
        Row: 'indexes + 'row,
    {
        Row::try_prepare_indexes_remove(&mut indexes.0, row, index)
    }
    fn commit_indexes_remove<'indexes>(prepared: Self::PreparedIndexesRemove<'indexes>)
    where
        Self: 'indexes,
        Row: 'indexes,
    {
        Row::commit_indexes_remove(prepared)
    }
    fn try_prepare_indexes_replace<'indexes, 'row>(
        indexes: &'indexes mut Self,
        current: Row::Ref<'row>,
        replacement: &Row,
        index: usize,
    ) -> Result<Self::PreparedIndexesReplace<'indexes>, Self::IndexesReplaceError>
    where
        Self: 'indexes,
        Row: 'indexes + 'row,
    {
        Row::try_prepare_indexes_replace(&mut indexes.0, current, replacement, index)
    }
    fn commit_indexes_replace<'indexes>(prepared: Self::PreparedIndexesReplace<'indexes>)
    where
        Self: 'indexes,
        Row: 'indexes,
    {
        Row::commit_indexes_replace(prepared)
    }
}

#[cfg(feature = "secondary-indexes")]
impl<Row: WarpTableRow> super::stable_slots::StableSlotResolver for AllocatedIndexes<Row>
where
    Row::Indexes: super::stable_slots::StableSlotResolver,
{
    fn resolve_stable_slot(
        &self,
        slot: crate::storage::StableSlot,
    ) -> Result<
        super::stable_slots::StableSlotResolveOutcome,
        super::stable_slots::StableSlotsInconsistency,
    > {
        self.0.resolve_stable_slot(slot)
    }
}