use serde::{Deserialize, Serialize};
use garage_db as db;
use garage_util::data::*;
use garage_util::migrate::Migrate;
use crate::crdt::Crdt;
pub trait PartitionKey:
Clone + PartialEq + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static
{
fn hash(&self) -> Hash;
}
impl PartitionKey for String {
fn hash(&self) -> Hash {
blake2sum(self.as_bytes())
}
}
impl PartitionKey for FixedBytes32 {
fn hash(&self) -> Hash {
*self
}
}
pub trait SortKey: Clone + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static {
fn sort_key(&self) -> &[u8];
}
impl SortKey for String {
fn sort_key(&self) -> &[u8] {
self.as_bytes()
}
}
impl SortKey for FixedBytes32 {
fn sort_key(&self) -> &[u8] {
self.as_slice()
}
}
pub trait Entry<P: PartitionKey, S: SortKey>:
Crdt + PartialEq + Clone + Migrate + Send + Sync + 'static
{
fn partition_key(&self) -> &P;
fn sort_key(&self) -> &S;
fn is_tombstone(&self) -> bool {
false
}
}
pub trait TableSchema: Send + Sync + 'static {
const TABLE_NAME: &'static str;
type P: PartitionKey;
type S: SortKey;
type E: Entry<Self::P, Self::S>;
type Filter: Clone + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static;
fn updated(
&self,
_tx: &mut db::Transaction,
_old: Option<&Self::E>,
_new: Option<&Self::E>,
) -> db::TxOpResult<()> {
Ok(())
}
fn matches_filter(entry: &Self::E, filter: &Self::Filter) -> bool;
}