use crate::error::PicanteResult;
use crate::key::{Key, QueryKindId};
use crate::persist::PersistableIngredient;
use crate::revision::Revision;
use futures_util::future::BoxFuture;
use std::collections::HashMap;
use std::sync::Arc;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct Touch {
pub changed_at: Revision,
}
pub trait DynIngredient<DB>: PersistableIngredient {
fn touch<'a>(&'a self, db: &'a DB, key: Key) -> BoxFuture<'a, PicanteResult<Touch>>;
}
pub struct IngredientRegistry<DB> {
ingredients: HashMap<QueryKindId, Arc<dyn DynIngredient<DB>>>,
}
impl<DB> Default for IngredientRegistry<DB> {
fn default() -> Self {
Self {
ingredients: HashMap::new(),
}
}
}
impl<DB> IngredientRegistry<DB> {
pub fn new() -> Self {
Self::default()
}
pub fn register<I>(&mut self, ingredient: Arc<I>)
where
I: DynIngredient<DB> + 'static,
{
let kind = ingredient.kind();
self.ingredients.insert(kind, ingredient);
}
pub fn ingredient(&self, kind: QueryKindId) -> Option<&dyn DynIngredient<DB>> {
self.ingredients.get(&kind).map(|i| i.as_ref())
}
pub fn persistable_ingredients(&self) -> Vec<&dyn PersistableIngredient> {
self.ingredients
.values()
.map(|i| i.as_ref() as &dyn PersistableIngredient)
.collect()
}
}
pub trait IngredientLookup: crate::runtime::HasRuntime + Sized {
fn ingredient(&self, kind: QueryKindId) -> Option<&dyn DynIngredient<Self>>;
}