use crate::DatabaseError;
use reth_db_api::table::{Compress, Decode, Decompress, DupSort, Encode, Key, Table, Value};
use serde::{Deserialize, Serialize};
pub type TableRawRow<T> = (RawKey<<T as Table>::Key>, RawValue<<T as Table>::Value>);
#[derive(Default, Copy, Clone, Debug)]
pub struct RawTable<T: Table> {
phantom: std::marker::PhantomData<T>,
}
impl<T: Table> Table for RawTable<T> {
const NAME: &'static str = T::NAME;
const DUPSORT: bool = false;
type Key = RawKey<T::Key>;
type Value = RawValue<T::Value>;
}
#[derive(Default, Copy, Clone, Debug)]
pub struct RawDupSort<T: DupSort> {
phantom: std::marker::PhantomData<T>,
}
impl<T: DupSort> Table for RawDupSort<T> {
const NAME: &'static str = T::NAME;
const DUPSORT: bool = true;
type Key = RawKey<T::Key>;
type Value = RawValue<T::Value>;
}
impl<T: DupSort> DupSort for RawDupSort<T> {
type SubKey = RawKey<T::SubKey>;
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct RawKey<K: Key> {
key: Vec<u8>,
_phantom: std::marker::PhantomData<K>,
}
impl<K: Key> RawKey<K> {
pub fn new(key: K) -> Self {
Self { key: K::encode(key).into(), _phantom: std::marker::PhantomData }
}
pub const fn from_vec(vec: Vec<u8>) -> Self {
Self { key: vec, _phantom: std::marker::PhantomData }
}
pub fn key(&self) -> Result<K, DatabaseError> {
K::decode(&self.key)
}
pub const fn raw_key(&self) -> &Vec<u8> {
&self.key
}
pub fn into_key(self) -> Vec<u8> {
self.key
}
}
impl<K: Key> From<K> for RawKey<K> {
fn from(key: K) -> Self {
Self::new(key)
}
}
impl AsRef<[u8]> for RawKey<Vec<u8>> {
fn as_ref(&self) -> &[u8] {
&self.key
}
}
impl<K: Key> Encode for RawKey<K> {
type Encoded = Vec<u8>;
fn encode(self) -> Self::Encoded {
self.key
}
}
impl<K: Key> Decode for RawKey<K> {
fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
Ok(Self { key: value.to_vec(), _phantom: std::marker::PhantomData })
}
fn decode_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
Ok(Self { key: value, _phantom: std::marker::PhantomData })
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Serialize, Ord, Hash)]
pub struct RawValue<V: Value> {
value: Vec<u8>,
#[serde(skip)]
_phantom: std::marker::PhantomData<V>,
}
impl<V: Value> RawValue<V> {
pub fn new(value: V) -> Self {
Self { value: V::compress(value).into(), _phantom: std::marker::PhantomData }
}
pub const fn from_vec(vec: Vec<u8>) -> Self {
Self { value: vec, _phantom: std::marker::PhantomData }
}
pub fn value(&self) -> Result<V, DatabaseError> {
V::decompress(&self.value)
}
pub fn raw_value(&self) -> &[u8] {
&self.value
}
pub fn into_value(self) -> Vec<u8> {
self.value
}
}
impl<V: Value> From<V> for RawValue<V> {
fn from(value: V) -> Self {
Self::new(value)
}
}
impl AsRef<[u8]> for RawValue<Vec<u8>> {
fn as_ref(&self) -> &[u8] {
&self.value
}
}
impl<V: Value> Compress for RawValue<V> {
type Compressed = Vec<u8>;
fn uncompressable_ref(&self) -> Option<&[u8]> {
Some(&self.value)
}
fn compress(self) -> Self::Compressed {
self.value
}
fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(self, buf: &mut B) {
buf.put_slice(self.value.as_slice())
}
}
impl<V: Value> Decompress for RawValue<V> {
fn decompress(value: &[u8]) -> Result<Self, DatabaseError> {
Ok(Self { value: value.to_vec(), _phantom: std::marker::PhantomData })
}
fn decompress_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
Ok(Self { value, _phantom: std::marker::PhantomData })
}
}