use std::ops::{Deref, DerefMut};
use crate::queries::filterable_types::Filterable;
#[allow(async_fn_in_trait)]
pub trait DataProvider<T>
where
T: Filterable,
Self: Sized,
{
type Error: std::fmt::Debug;
type CreateRequest: Default;
async fn all(&self) -> Result<impl Iterator<Item = T>, Self::Error>;
async fn get(
&self,
predicate: impl Fn(T::FilterType) -> crate::queries::Filter,
) -> Result<Option<T>, Self::Error>;
async fn create(
&self,
item: Self::CreateRequest,
) -> Result<T, Self::Error>; async fn delete(
&self,
item: T, ) -> Result<(), Self::Error>;
async fn update(
&self,
item: &T,
) -> Result<(), Self::Error>;
}
pub trait WithFilter<T>
where
T: Filterable,
{
type R;
fn with_filter(
&self,
predicate: impl Fn(T::FilterType) -> crate::queries::Filter,
) -> Self::R;
}
pub struct Provided<'a, T, P>
where
P: DataProvider<T>,
T: Filterable,
{
provider: &'a P,
data: T,
}
impl<'a, T, P> DerefMut for Provided<'a, T, P>
where
P: DataProvider<T>,
T: Filterable,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl<'a, T, P> Deref for Provided<'a, T, P>
where
P: DataProvider<T>,
T: Filterable,
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.data
}
}
#[allow(unused)]
impl<'a, T, P> Provided<'a, T, P>
where
P: DataProvider<T>,
T: Filterable,
{
async fn save(&self) -> Result<(), <P as DataProvider<T>>::Error> {
self.provider.update(&self.data).await
}
async fn delete(self) -> Result<(), <P as DataProvider<T>>::Error> {
self.provider.delete(self.data).await
}
}