use std::fmt::Debug;
use const_fnv1a_hash::fnv1a_hash_str_32;
use crate::{
Cid, GetType, KeyScheme, Typ,
types::{ArmourError, EntityAttribute},
};
pub enum MigrationRes<Item: Record> {
Unchanged(Item::SelfId, Item),
Changed {
migration_type: MigrationType,
new_key: Item::SelfId,
new_value: Item,
},
Deleted,
}
pub type MigrationFn<Item, Val> = fn(&[u8], &Val) -> MigrationRes<Item>;
#[derive(Debug, Clone, Copy)]
pub enum MigrationType {
Key,
Value,
Entry,
}
pub type Migration<Item, Val> = (u16, MigrationFn<Item, Val>);
pub trait Record: Sized + GetType + 'static {
type SelfId: Cid + Debug;
type Value: Debug + Clone;
const NAME: &'static str;
const ID: u32 = fnv1a_hash_str_32(Self::NAME);
const VERSION: u16 = 0;
const MIGRATIONS: &'static [Migration<Self, Self::Value>] = &[];
const ATTRIBUTES: EntityAttribute = EntityAttribute::from_ty::<Self>();
const SIZE: Option<usize> = None;
fn deser(bytes: &Self::Value) -> Self;
fn deser_owned(bytes: Self::Value) -> Self {
Self::deser(&bytes)
}
fn try_deser(bytes: &Self::Value) -> Result<Self, ArmourError> {
Ok(Self::deser(bytes))
}
fn ser(&self) -> Self::Value;
fn ser_owned(self) -> Self::Value {
Self::ser(&self)
}
#[inline]
fn deser_key(key: &[u8]) -> Self::SelfId {
<Self as Record>::SelfId::from_bytes(key).expect("cannot deserialize key")
}
#[inline]
fn try_deser_key(key: &[u8]) -> Result<Self::SelfId, ArmourError> {
<Self as Record>::SelfId::from_bytes(key)
}
}
pub const fn record_types_tuple<R>() -> (KeyScheme, Typ)
where
R: Record + GetType,
{
let key_type = R::SelfId::TY;
let val_type = R::TYPE;
(key_type, val_type)
}