use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
use super::btree_entry::KeyOperation;
use crate::{error::Error, ArcBytes, ErrorKind};
#[derive(Debug)]
pub struct Modification<'a, T> {
pub transaction_id: Option<u64>,
pub keys: Vec<ArcBytes<'a>>,
pub operation: Operation<'a, T>,
}
impl<'a, T> Modification<'a, T> {
pub(crate) fn reverse(&mut self) -> Result<(), Error> {
if self.keys.windows(2).all(|w| w[0] < w[1]) {
self.keys.reverse();
if let Operation::SetEach(values) = &mut self.operation {
values.reverse();
}
Ok(())
} else {
Err(Error::from(ErrorKind::KeysNotOrdered))
}
}
}
pub enum Operation<'a, T> {
Set(T),
SetEach(Vec<T>),
Remove,
CompareSwap(CompareSwap<'a, T>),
}
impl<'a, T: Debug> Debug for Operation<'a, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Set(arg0) => f.debug_tuple("Set").field(arg0).finish(),
Self::SetEach(arg0) => f.debug_tuple("SetEach").field(arg0).finish(),
Self::Remove => write!(f, "Remove"),
Self::CompareSwap(_) => f.debug_tuple("CompareSwap").finish(),
}
}
}
pub type CompareSwapFn<'a, T> = dyn FnMut(&ArcBytes<'a>, Option<T>) -> KeyOperation<T> + 'a;
pub struct CompareSwap<'a, T>(&'a mut CompareSwapFn<'a, T>);
impl<'a, T> CompareSwap<'a, T> {
pub fn new<F: FnMut(&ArcBytes<'_>, Option<T>) -> KeyOperation<T> + 'a>(
callback: &'a mut F,
) -> Self {
Self(callback)
}
}
impl<'a, T> Debug for CompareSwap<'a, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("CompareSwap(dyn FnMut)")
}
}
impl<'a, T> Deref for CompareSwap<'a, T> {
type Target = CompareSwapFn<'a, T>;
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<'a, T> DerefMut for CompareSwap<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0
}
}