use std::hash::Hash;
use crate::internal::storage::{
ErasedInternedStorage,
ErasedPushableStorage,
ErasedQueryStorage,
ErasedTrackedStorage,
InternedStorage,
PushableStorage,
QueryStorage,
RouteBuilder,
TrackedStorage,
};
pub trait StorageOf<T: Storable> {
fn storage_index(&self) -> u16;
}
pub trait Storage {
fn init_routing(table: &mut RouteBuilder)
where
Self: Sized;
fn tracked_storage(&self, index: u16) -> Option<&dyn ErasedTrackedStorage>;
fn query_storage(&self, index: u16) -> Option<&dyn ErasedQueryStorage>;
fn pushable_storage(&self, index: u16) -> Option<&dyn ErasedPushableStorage>;
fn interned_storage(&self, index: u16) -> Option<&dyn ErasedInternedStorage>;
}
pub trait DbWith<S> {
fn storage_struct_index(&self) -> u16;
}
pub trait Tracked: Eq + Storable<Storage = TrackedStorage<Self>> {
#[cfg(feature = "serde")]
type Id: Eq + Hash + Clone + Send + Sync + serde::Serialize + for<'de> serde::Deserialize<'de>;
#[cfg(not(feature = "serde"))]
type Id: Eq + Hash + Clone + Send + Sync;
fn id(&self) -> &Self::Id;
}
pub trait Pushable: Storable<Storage = PushableStorage<Self>> {}
pub trait Query: Storable<Storage = QueryStorage<Self>> {
#[cfg(feature = "serde")]
type Input: Eq + Hash + Send + Sync + serde::Serialize + for<'de> serde::Deserialize<'de>;
#[cfg(not(feature = "serde"))]
type Input: Eq + Hash + Send + Sync;
type Output: Tracked + Send + Sync;
}
pub trait Interned: Clone + Eq + Hash + Storable<Storage = InternedStorage<Self>> {}
pub trait Storable: Sized + Send + 'static {
type Storage: Default + extra::ExtraBound;
fn tracked_storage(store: &Self::Storage) -> Option<&dyn ErasedTrackedStorage>;
fn query_storage(store: &Self::Storage) -> Option<&dyn ErasedQueryStorage>;
fn pushable_storage(store: &Self::Storage) -> Option<&dyn ErasedPushableStorage>;
fn interned_storage(store: &Self::Storage) -> Option<&dyn ErasedInternedStorage>;
}
#[cfg(feature = "test")]
mod extra {
use crate::test::StorageType;
pub trait ExtraBound: Into<StorageType> {}
impl<T: Into<StorageType>> ExtraBound for T {}
}
#[cfg(not(feature = "test"))]
mod extra {
pub trait ExtraBound {}
impl<T> ExtraBound for T {}
}
macro_rules! intern {
($t:ty) => {
impl Interned for $t {}
impl Storable for $t {
type Storage = InternedStorage<Self>;
fn tracked_storage(_store: &Self::Storage) -> Option<&dyn ErasedTrackedStorage> { None }
fn query_storage(_store: &Self::Storage) -> Option<&dyn ErasedQueryStorage> { None }
fn pushable_storage(_store: &Self::Storage) -> Option<&dyn ErasedPushableStorage> { None }
fn interned_storage(store: &Self::Storage) -> Option<&dyn ErasedInternedStorage> { Some(store) }
}
};
}
intern!(String);