use super::super::dense_key_index::{PrepareRemoveOutcome, PreparedRemoval};
use super::{IndexKey, UniqueIndex, UniqueIndexInconsistency};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum UniqueIndexRemoveError<Key> {
Absent {
key: Key,
},
Inconsistent {
key: Key,
reason: UniqueIndexInconsistency,
},
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[must_use]
pub enum UniqueIndexRemoveOutcome<Key> {
Removed { key: Key, row: usize },
}
pub struct PreparedUniqueIndexRemove<'index, Key: IndexKey> {
index: &'index mut UniqueIndex<Key>,
removal: PreparedRemoval<Key>,
key: Key,
}
impl<Key: IndexKey> UniqueIndex<Key> {
pub fn try_prepare_remove(
&mut self,
key: Key,
) -> Result<PreparedUniqueIndexRemove<'_, Key>, UniqueIndexRemoveError<Key>> {
let Some(last_row) = self.keys.len().checked_sub(1) else {
return Err(UniqueIndexRemoveError::Absent { key });
};
let removal = self
.key_index
.prepare_remove(key, &self.keys, last_row)
.map_err(|reason| UniqueIndexRemoveError::Inconsistent {
key,
reason: reason.into(),
})?;
let PrepareRemoveOutcome::Prepared(removal) = removal else {
return Err(UniqueIndexRemoveError::Absent { key });
};
Ok(PreparedUniqueIndexRemove {
index: self,
removal,
key,
})
}
}
impl<Key: IndexKey> PreparedUniqueIndexRemove<'_, Key> {
pub fn commit(self) -> UniqueIndexRemoveOutcome<Key> {
let row = self.removal.row;
self.index
.key_index
.commit_remove(self.removal, &self.index.keys);
self.index.keys.swap_remove(row);
UniqueIndexRemoveOutcome::Removed { key: self.key, row }
}
}