use std::error::Error;
use std::future::Future;
use std::pin::Pin;
use crate::command::{ApplyKeepsake, RevokeKeepsake};
use crate::model::{
ActiveRelation, FulfillmentSnapshot, Keepsake, KeepsakeId, RelationId, RelationKey, SubjectRef,
};
#[cfg(any(test, feature = "test"))]
mod memory;
#[cfg(any(test, feature = "test"))]
pub use memory::{
ActiveRelationSeed, InMemoryActiveRelations, InMemoryActiveRelationsError,
InMemoryFulfillmentProvider, InMemoryFulfillmentProviderError, InMemoryKeepsakeStore,
InMemoryKeepsakeStoreError,
};
pub type ProviderResult<T, E> = core::result::Result<T, E>;
pub trait FulfillmentProvider: Send + Sync {
type Error: Error + Send + Sync + 'static;
fn snapshot(
&self,
keepsake: &Keepsake,
) -> ProviderResult<Option<FulfillmentSnapshot>, Self::Error>;
}
pub trait KeepsakeStore: Send + Sync {
type Error: Error + Send + Sync + 'static;
fn apply(&self, command: &ApplyKeepsake) -> ProviderResult<Keepsake, Self::Error>;
fn revoke(&self, command: &RevokeKeepsake) -> ProviderResult<Keepsake, Self::Error>;
fn active_for_subject(
&self,
subject: &SubjectRef,
) -> ProviderResult<Vec<Keepsake>, Self::Error>;
fn get(&self, id: KeepsakeId) -> ProviderResult<Option<Keepsake>, Self::Error>;
}
pub trait ActiveRelationSource: Send + Sync {
type Error: Error + Send + Sync + 'static;
fn active_relations_for_subject<'a>(
&'a self,
subject: &'a SubjectRef,
) -> impl Future<Output = ProviderResult<Vec<ActiveRelation>, Self::Error>> + Send + 'a;
fn active_relations_for_subject_by_ids<'a>(
&'a self,
subject: &'a SubjectRef,
relation_ids: &'a [RelationId],
) -> impl Future<Output = ProviderResult<Vec<ActiveRelation>, Self::Error>> + Send + 'a;
fn active_relations_for_subject_by_keys<'a>(
&'a self,
subject: &'a SubjectRef,
keys: &'a [RelationKey],
) -> impl Future<Output = ProviderResult<Vec<ActiveRelation>, Self::Error>> + Send + 'a;
}
pub type DynActiveRelationFuture<'a, E> =
Pin<Box<dyn Future<Output = ProviderResult<Vec<ActiveRelation>, E>> + Send + 'a>>;
pub trait DynActiveRelationSource: Send + Sync {
type Error: Error + Send + Sync + 'static;
fn active_relations_for_subject<'a>(
&'a self,
subject: &'a SubjectRef,
) -> DynActiveRelationFuture<'a, Self::Error>;
fn active_relations_for_subject_by_ids<'a>(
&'a self,
subject: &'a SubjectRef,
relation_ids: &'a [RelationId],
) -> DynActiveRelationFuture<'a, Self::Error>;
fn active_relations_for_subject_by_keys<'a>(
&'a self,
subject: &'a SubjectRef,
keys: &'a [RelationKey],
) -> DynActiveRelationFuture<'a, Self::Error>;
}
impl<T> DynActiveRelationSource for T
where
T: ActiveRelationSource,
{
type Error = T::Error;
fn active_relations_for_subject<'a>(
&'a self,
subject: &'a SubjectRef,
) -> DynActiveRelationFuture<'a, Self::Error> {
Box::pin(ActiveRelationSource::active_relations_for_subject(
self, subject,
))
}
fn active_relations_for_subject_by_ids<'a>(
&'a self,
subject: &'a SubjectRef,
relation_ids: &'a [RelationId],
) -> DynActiveRelationFuture<'a, Self::Error> {
Box::pin(ActiveRelationSource::active_relations_for_subject_by_ids(
self,
subject,
relation_ids,
))
}
fn active_relations_for_subject_by_keys<'a>(
&'a self,
subject: &'a SubjectRef,
keys: &'a [RelationKey],
) -> DynActiveRelationFuture<'a, Self::Error> {
Box::pin(ActiveRelationSource::active_relations_for_subject_by_keys(
self, subject, keys,
))
}
}