use rapira::Rapira;
use strum::IntoStaticStr;
use crate::logdb::{ByteValue, KeyValue};
#[derive(Debug, Clone, IntoStaticStr)]
pub enum ChangeEvent {
Upsert(KeyValue),
Delete(ByteValue),
}
impl ChangeEvent {
pub fn variant(&self) -> &'static str {
self.into()
}
pub fn key(&self) -> &ByteValue {
match self {
ChangeEvent::Upsert(kv) => &kv.0,
ChangeEvent::Delete(key) => key,
}
}
pub fn from_kv(key: ByteValue, val: Option<ByteValue>) -> Self {
match val {
Some(val) => ChangeEvent::Upsert((key, val)),
None => ChangeEvent::Delete(key),
}
}
}
impl Rapira for ChangeEvent {
const MIN_SIZE: usize = 5;
fn size(&self) -> usize {
1 + match self {
ChangeEvent::Upsert((k, v)) => k.len() + v.len(),
ChangeEvent::Delete(k) => k.len(),
}
}
fn check_bytes(slice: &mut &[u8]) -> rapira::Result<()> {
let var = rapira::byte_rapira::from_slice(slice)?;
match var {
0 => {
rapira::bytes_rapira::check_bytes::<()>(Default::default(), slice)?;
rapira::bytes_rapira::check_bytes::<()>(Default::default(), slice)?;
Ok(())
}
1 => Ok(()),
_ => Err(rapira::RapiraError::EnumVariant),
}
}
fn from_slice(slice: &mut &[u8]) -> rapira::Result<Self>
where
Self: Sized,
{
let var = rapira::byte_rapira::from_slice(slice)?;
match var {
0 => {
let key = rapira::bytes_rapira::from_slice(slice)?;
let val = rapira::bytes_rapira::from_slice(slice)?;
Ok(ChangeEvent::Upsert((key.into(), val.into())))
}
1 => {
let key = rapira::bytes_rapira::from_slice(slice)?;
Ok(ChangeEvent::Delete(key.into()))
}
_ => Err(rapira::RapiraError::EnumVariant),
}
}
fn convert_to_bytes(&self, slice: &mut [u8], cursor: &mut usize) {
match self {
ChangeEvent::Upsert((k, v)) => {
rapira::byte_rapira::convert_to_bytes(&0, slice, cursor);
rapira::bytes_rapira::convert_to_bytes(k, slice, cursor);
rapira::bytes_rapira::convert_to_bytes(v, slice, cursor);
}
ChangeEvent::Delete(k) => {
rapira::byte_rapira::convert_to_bytes(&1, slice, cursor);
rapira::bytes_rapira::convert_to_bytes(k, slice, cursor);
}
}
}
}