use std::error::Error;
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::path::Path;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "digest")]
use digest::Digest;
use crate::Array;
use std::convert::Infallible;
use std::num::TryFromIntError;
pub trait Hasher<const N: usize> {
fn new(size: usize) -> Self;
fn update(&mut self, data: &[u8]);
fn finalize(self) -> Array<N>;
}
#[cfg(feature = "digest")]
impl<T: Digest + Default, const N: usize> Hasher<N> for T {
fn new(_size: usize) -> Self {
Self::default()
}
fn update(&mut self, data: &[u8]) {
self.update(data);
}
fn finalize(self) -> Array<N> {
#[cfg(feature = "serde")]
let mut finalized = Array([0; N]);
#[cfg(not(any(feature = "serde")))]
let mut finalized = [0; N];
let result = self.finalize();
let mut size = finalized.as_ref().len();
if size > result.len() {
size = result.len();
}
finalized.as_mut()[..size].copy_from_slice(&result[..size]);
finalized
}
}
pub trait Branch<const N: usize> {
fn new() -> Self;
fn get_count(&self) -> u64;
fn get_zero(&self) -> &Array<N>;
fn get_one(&self) -> &Array<N>;
fn get_split_index(&self) -> usize;
fn get_key(&self) -> &Array<N>;
fn set_count(&mut self, count: u64);
fn set_zero(&mut self, zero: Array<N>);
fn set_one(&mut self, one: Array<N>);
fn set_split_index(&mut self, index: usize);
fn set_key(&mut self, key: Array<N>);
fn decompose(self) -> (u64, Array<N>, Array<N>, usize, Array<N>);
}
pub trait Leaf<const N: usize> {
fn new() -> Self;
fn get_key(&self) -> &Array<N>;
fn get_data(&self) -> &Array<N>;
fn set_key(&mut self, key: Array<N>);
fn set_data(&mut self, data: Array<N>);
fn decompose(self) -> (Array<N>, Array<N>);
}
pub trait Data {
fn new() -> Self;
fn get_value(&self) -> &[u8];
fn set_value(&mut self, value: &[u8]);
}
pub trait Node<const N: usize> {
type Branch: Branch<N>;
type Leaf: Leaf<N>;
type Data: Data;
fn new(node_variant: NodeVariant<Self::Branch, Self::Leaf, Self::Data, N>) -> Self;
fn get_references(&self) -> u64;
fn get_variant(self) -> NodeVariant<Self::Branch, Self::Leaf, Self::Data, N>;
fn set_references(&mut self, references: u64);
fn set_branch(&mut self, branch: Self::Branch);
fn set_leaf(&mut self, leaf: Self::Leaf);
fn set_data(&mut self, data: Self::Data);
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(any(feature = "serde",), derive(Serialize, Deserialize))]
#[non_exhaustive]
pub enum NodeVariant<BranchType: Branch<N>, LeafType: Leaf<N>, DataType: Data, const N: usize> {
Branch(BranchType),
Leaf(LeafType),
Data(DataType),
}
pub trait Database<const N: usize, M: Node<N>> {
type EntryType;
fn open(path: &Path) -> Result<Self, Exception>
where
Self: Sized;
fn get_node(&self, key: Array<N>) -> Result<Option<M>, Exception>;
fn insert(&mut self, key: Array<N>, node: M) -> Result<(), Exception>;
fn remove(&mut self, key: &Array<N>) -> Result<(), Exception>;
fn batch_write(&mut self) -> Result<(), Exception>;
}
pub trait Encode {
fn encode(&self) -> Result<Vec<u8>, Exception>;
}
impl Encode for Vec<u8> {
#[inline]
fn encode(&self) -> Result<Self, Exception> {
Ok(self.clone())
}
}
pub trait Decode {
fn decode(buffer: &[u8]) -> Result<Self, Exception>
where
Self: Sized;
}
impl Decode for Vec<u8> {
#[inline]
fn decode(buffer: &[u8]) -> Result<Self, Exception> {
Ok(buffer.to_vec())
}
}
#[derive(Debug)]
pub struct Exception {
details: String,
}
impl Exception {
#[inline]
#[must_use]
pub fn new(details: &str) -> Self {
Self {
details: details.to_owned(),
}
}
}
impl Display for Exception {
#[inline]
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{}", self.details)
}
}
impl Error for Exception {
#[inline]
fn description(&self) -> &str {
&self.details
}
}
impl From<Infallible> for Exception {
#[inline]
fn from(_inf: Infallible) -> Self {
Self::new("Infallible")
}
}
impl From<TryFromIntError> for Exception {
#[inline]
fn from(err: TryFromIntError) -> Self {
Self::new(&err.to_string())
}
}