use std::ops::ControlFlow;
use armour_core::{GetRefs, GetType, StorageClass};
use crate::access::Access;
use crate::armour::collection::Collection;
use crate::key::Key;
use crate::{CollectionMeta, DbResult};
mod sealed {
pub trait Sealed {}
}
pub trait IndexTarget: SchemaCollection {
fn put_entry(&self, k: &Self::K, v: &Self::V) -> DbResult<()>;
fn delete_entry(&self, k: &Self::K) -> DbResult<()>;
}
pub trait SchemaCollection: Collection + Send + Sync + 'static + sealed::Sealed {
type K: Key + GetRefs + GetType + 'static;
type V: CollectionMeta + GetRefs + 'static;
const STORAGE: StorageClass;
fn scan(&self, f: &mut dyn FnMut(&Self::K, &Self::V));
fn undecodable_rows(&self) -> u64 {
0
}
#[doc(hidden)]
fn effective_projection_limits(&self) -> Option<(usize, usize)> {
None
}
fn contains_key(&self, key: &Self::K) -> bool;
fn with_value(&self, key: &Self::K, f: &mut dyn FnMut(&Self::V)) -> bool;
}
impl<S, K, V> sealed::Sealed for S
where
S: Access<Key = K, Val = V> + Collection,
K: Key + GetRefs + GetType + 'static,
V: CollectionMeta + GetRefs + 'static,
{
}
impl<S, K, V> SchemaCollection for S
where
S: Access<Key = K, Val = V> + Collection,
K: Key + GetRefs + GetType + 'static,
V: CollectionMeta + GetRefs + 'static,
{
type K = K;
type V = V;
const STORAGE: StorageClass = S::STORAGE;
fn scan(&self, f: &mut dyn FnMut(&Self::K, &Self::V)) {
Access::scan_all(self, &mut |row| {
if let Ok((k, v)) = row {
f(k, v);
}
ControlFlow::Continue(())
});
}
fn undecodable_rows(&self) -> u64 {
Access::undecodable_rows(self)
}
fn effective_projection_limits(&self) -> Option<(usize, usize)> {
Access::effective_projection_limits(self)
}
fn contains_key(&self, key: &Self::K) -> bool {
Access::contains(self, key).unwrap_or(false)
}
fn with_value(&self, key: &Self::K, f: &mut dyn FnMut(&Self::V)) -> bool {
matches!(Access::with_value(self, key, |v| f(v)), Ok(Some(())))
}
}
impl<S, K, V> IndexTarget for S
where
S: Access<Key = K, Val = V> + Collection,
K: Key + GetRefs + GetType + 'static,
V: CollectionMeta + GetRefs + 'static,
{
fn put_entry(&self, k: &Self::K, v: &Self::V) -> DbResult<()> {
Access::put_ref(self, k, v)
}
fn delete_entry(&self, k: &Self::K) -> DbResult<()> {
Access::delete(self, k)
}
}