use std::marker::PhantomData;
use crate::{bytes::Bytes, node::Leaf, ToBytes};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Data<'b, 'tx> {
Bucket(BucketName<'b, 'tx>),
KeyValue(KVPair<'b, 'tx>),
}
impl<'b, 'tx> Data<'b, 'tx> {
pub fn is_kv(&self) -> bool {
matches!(self, Data::KeyValue(_))
}
pub fn kv(&self) -> &KVPair {
if let Self::KeyValue(kv) = self {
return kv;
}
panic!("Cannot get KVPair from BucketData");
}
pub fn key(&self) -> &[u8] {
match self {
Self::Bucket(b) => b.name(),
Self::KeyValue(kv) => kv.key(),
}
}
}
impl<'b, 'tx> From<Leaf<'tx>> for Data<'b, 'tx> {
fn from(val: Leaf<'tx>) -> Self {
match val {
Leaf::Bucket(name, _) => Data::Bucket(BucketName::new(name)),
Leaf::Kv(key, value) => Data::KeyValue(KVPair::new(key, value)),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BucketName<'b, 'tx> {
name: Bytes<'tx>,
_phantom: PhantomData<&'b ()>,
}
impl<'b, 'tx> BucketName<'b, 'tx> {
pub(crate) fn new(name: Bytes<'tx>) -> Self {
BucketName {
name,
_phantom: PhantomData,
}
}
pub fn name(&self) -> &[u8] {
self.name.as_ref()
}
}
impl<'b, 'tx> ToBytes<'tx> for BucketName<'b, 'tx> {
fn to_bytes(self) -> Bytes<'tx> {
self.name
}
}
impl<'b, 'tx> ToBytes<'tx> for &BucketName<'b, 'tx> {
fn to_bytes(self) -> Bytes<'tx> {
self.name.clone()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KVPair<'b, 'tx> {
key: Bytes<'tx>,
value: Bytes<'tx>,
_phantom: PhantomData<&'b ()>,
}
impl<'b, 'tx> KVPair<'b, 'tx> {
pub(crate) fn new(key: Bytes<'tx>, value: Bytes<'tx>) -> Self {
KVPair {
key,
value,
_phantom: PhantomData,
}
}
pub fn key(&self) -> &[u8] {
self.key.as_ref()
}
pub fn value(&self) -> &[u8] {
self.value.as_ref()
}
pub fn kv(&self) -> (&[u8], &[u8]) {
(self.key(), self.value())
}
}
impl<'b, 'tx> From<(Bytes<'tx>, Bytes<'tx>)> for KVPair<'b, 'tx> {
fn from(val: (Bytes<'tx>, Bytes<'tx>)) -> Self {
KVPair::new(val.0, val.1)
}
}
impl<'b, 'tx> From<Leaf<'tx>> for Option<KVPair<'b, 'tx>> {
fn from(val: Leaf<'tx>) -> Self {
match val {
Leaf::Bucket(_, _) => None,
Leaf::Kv(key, value) => Some(KVPair::new(key, value)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_kv_pair() {
let k = vec![1, 2, 3, 4];
let v = vec![5, 6, 7, 8, 9, 0];
let kv = KVPair::new(Bytes::Slice(&k), Bytes::Slice(&v));
assert_eq!(kv.key(), &k[..]);
assert_eq!(kv.value(), &v[..]);
let kv = KVPair::new(Bytes::Slice(&k), Bytes::Slice(&v));
assert_eq!(kv.key(), &k[..]);
assert_eq!(kv.value(), &v[..]);
}
}