use crate::session::Session;
use std::{rc::Rc, sync::Arc};
use url::Url;
#[async_trait::async_trait(?Send)]
pub trait Repo {
type Error: 'static;
async fn fetch<D: Dereference, S: Session>(
&self,
id: D,
session: S,
) -> Result<Option<D::Output>, Self::Error>;
}
pub trait RepoFactory {
type Repo: Repo;
type Crypto;
fn build_repo(&self, crypto: Self::Crypto) -> Self::Repo;
}
pub trait Dereference {
type Output: serde::de::DeserializeOwned;
fn url(&self) -> &Url;
}
impl<'a, T> Dereference for &'a T
where
T: Dereference,
{
type Output = T::Output;
fn url(&self) -> &Url {
T::url(self)
}
}
impl<'a, T> Dereference for &'a mut T
where
T: Dereference,
{
type Output = T::Output;
fn url(&self) -> &Url {
T::url(self)
}
}
impl<T> Dereference for Box<T>
where
T: Dereference,
{
type Output = T::Output;
fn url(&self) -> &Url {
T::url(self)
}
}
impl<T> Dereference for Rc<T>
where
T: Dereference,
{
type Output = T::Output;
fn url(&self) -> &Url {
T::url(self)
}
}
impl<T> Dereference for Arc<T>
where
T: Dereference,
{
type Output = T::Output;
fn url(&self) -> &Url {
T::url(self)
}
}
#[async_trait::async_trait(?Send)]
impl<'a, T> Repo for &'a T
where
T: Repo,
{
type Error = T::Error;
async fn fetch<D: Dereference, S: Session>(
&self,
id: D,
session: S,
) -> Result<Option<D::Output>, Self::Error> {
T::fetch(self, id, session).await
}
}
#[async_trait::async_trait(?Send)]
impl<'a, T> Repo for &'a mut T
where
T: Repo,
{
type Error = T::Error;
async fn fetch<D: Dereference, S: Session>(
&self,
id: D,
session: S,
) -> Result<Option<D::Output>, Self::Error> {
T::fetch(self, id, session).await
}
}
#[async_trait::async_trait(?Send)]
impl<T> Repo for Box<T>
where
T: Repo,
{
type Error = T::Error;
async fn fetch<D: Dereference, S: Session>(
&self,
id: D,
session: S,
) -> Result<Option<D::Output>, Self::Error> {
T::fetch(self, id, session).await
}
}
#[async_trait::async_trait(?Send)]
impl<T> Repo for Rc<T>
where
T: Repo,
{
type Error = T::Error;
async fn fetch<D: Dereference, S: Session>(
&self,
id: D,
session: S,
) -> Result<Option<D::Output>, Self::Error> {
T::fetch(self, id, session).await
}
}
#[async_trait::async_trait(?Send)]
impl<T> Repo for Arc<T>
where
T: Repo,
{
type Error = T::Error;
async fn fetch<D: Dereference, S: Session>(
&self,
id: D,
session: S,
) -> Result<Option<D::Output>, Self::Error> {
T::fetch(self, id, session).await
}
}