#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum Op {
Put(Vec<u8>),
Delete,
}
#[derive(Debug, Default, Clone)]
pub struct Batch {
ops: Vec<(Vec<u8>, Op)>,
}
impl Batch {
#[inline]
#[must_use]
pub fn new() -> Self {
Batch { ops: Vec::new() }
}
pub fn put(&mut self, key: impl AsRef<[u8]>, value: impl AsRef<[u8]>) {
self.ops
.push((key.as_ref().to_vec(), Op::Put(value.as_ref().to_vec())));
}
pub fn delete(&mut self, key: impl AsRef<[u8]>) {
self.ops.push((key.as_ref().to_vec(), Op::Delete));
}
#[inline]
#[must_use]
pub fn len(&self) -> usize {
self.ops.len()
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.ops.is_empty()
}
pub(crate) fn into_ops(self) -> Vec<(Vec<u8>, Op)> {
self.ops
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn test_new_batch_is_empty() {
let b = Batch::new();
assert!(b.is_empty());
assert_eq!(b.len(), 0);
}
#[test]
fn test_records_operations_in_order() {
let mut b = Batch::new();
b.put(b"a", b"1");
b.delete(b"b");
let ops = b.into_ops();
assert_eq!(ops[0], (b"a".to_vec(), Op::Put(b"1".to_vec())));
assert_eq!(ops[1], (b"b".to_vec(), Op::Delete));
}
#[test]
fn test_accepts_vec_and_slice_keys() {
let mut b = Batch::new();
b.put(vec![1u8, 2, 3], vec![4u8]);
b.put([9u8, 8].as_slice(), [7u8].as_slice());
assert_eq!(b.len(), 2);
}
}