use core::ops::Range;
use std::error::Error;
use std::fmt::{Debug, Display};
use crate::{BufferOp, BufferOverflowError, BufferOverflowOr, Repository, Storage, Unifier};
use serde::Serialize;
#[derive(Debug)]
pub enum SledStorageError {
Sled(sled::Error),
Serialization(postcard::Error),
Deserialization(postcard::Error),
BufferOverflow,
}
impl Display for SledStorageError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Sled(e) => write!(f, "Sled error: {e}"),
Self::Serialization(e) => write!(f, "Serialization error: {e}"),
Self::Deserialization(e) => write!(f, "Deserialization error: {e}"),
Self::BufferOverflow => write!(f, "Buffer overflow"),
}
}
}
impl Error for SledStorageError {}
impl From<sled::Error> for SledStorageError {
fn from(e: sled::Error) -> Self {
Self::Sled(e)
}
}
impl From<postcard::Error> for SledStorageError {
fn from(e: postcard::Error) -> Self {
Self::Serialization(e)
}
}
impl From<BufferOverflowError> for SledStorageError {
fn from(_: BufferOverflowError) -> Self {
Self::BufferOverflow
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct PostcardUnifier;
impl Unifier for PostcardUnifier {
type D = Vec<u8>;
type SerError = postcard::Error;
type DeError = postcard::Error;
fn serialize(
&self,
buffer: &mut Self::D,
data: impl Serialize,
) -> Result<(usize, usize), BufferOverflowOr<Self::SerError>> {
let start = buffer.len();
let serialized = postcard::to_allocvec(&data)?;
buffer.extend_from_slice(&serialized);
Ok((start, buffer.len()))
}
fn deserialize<T: serde::de::DeserializeOwned>(
&self,
data: &Self::D,
) -> Result<T, Self::DeError> {
postcard::from_bytes(data)
}
}
impl Storage for sled::Db {
type Repo = Self;
type KeyUnifier = PostcardUnifier;
type ValueUnifier = PostcardUnifier;
type Container = Vec<BufferOp>;
fn repository(&self) -> &Self::Repo {
self
}
fn repository_mut(&mut self) -> &mut Self::Repo {
self
}
}
impl Repository for sled::Db {
type K = Vec<u8>;
type V = Vec<u8>;
type Error = SledStorageError;
fn insert_entry(&mut self, key: &[u8], value: &[u8]) -> Result<(), Self::Error> {
self.insert(key, value)?;
Ok(())
}
fn get_entry(&self, key: &[u8]) -> Result<Option<Self::V>, Self::Error> {
match self.get(key)? {
Some(ivec) => Ok(Some(ivec.to_vec())),
None => Ok(None),
}
}
fn remove_entry(&mut self, key: &[u8]) -> Result<Option<Self::V>, Self::Error> {
match self.remove(key)? {
Some(ivec) => Ok(Some(ivec.to_vec())),
None => Ok(None),
}
}
fn scan_range(
&self,
range: Range<Self::K>,
) -> Result<impl Iterator<Item = Result<Self::K, Self::Error>>, Self::Error> {
let keys: Vec<_> = self
.range(range.start..range.end)
.filter_map(Result::ok)
.map(|(k, _)| k.to_vec())
.collect();
Ok(keys.into_iter().rev().map(Ok))
}
fn apply<'a>(
&mut self,
operations: impl Iterator<Item = crate::BatchOp<'a, Self::K, Self::V>>,
) -> Result<(), Self::Error> {
let mut batch = sled::Batch::default();
for op in operations {
match op {
crate::BatchOp::Insert { key, value } => {
batch.insert(key, value);
}
crate::BatchOp::Delete { key } => {
batch.remove(key);
}
}
}
self.apply_batch(batch)?;
Ok(())
}
}