1use std::error::Error;
4use std::future::Future;
5use std::pin::Pin;
6
7use crate::command::{ApplyKeepsake, RevokeKeepsake};
8use crate::model::{
9 ActiveRelation, FulfillmentSnapshot, Keepsake, KeepsakeId, RelationId, RelationKey, SubjectRef,
10};
11
12#[cfg(any(test, feature = "test"))]
13mod memory;
14
15#[cfg(any(test, feature = "test"))]
16pub use memory::{ActiveRelationSeed, InMemoryActiveRelations, InMemoryActiveRelationsError};
17
18pub type ProviderResult<T, E> = core::result::Result<T, E>;
20
21pub trait FulfillmentProvider: Send + Sync {
23 type Error: Error + Send + Sync + 'static;
25
26 fn snapshot(
28 &self,
29 keepsake: &Keepsake,
30 ) -> ProviderResult<Option<FulfillmentSnapshot>, Self::Error>;
31}
32
33pub trait KeepsakeStore: Send + Sync {
35 type Error: Error + Send + Sync + 'static;
37
38 fn apply(&self, command: &ApplyKeepsake) -> ProviderResult<Keepsake, Self::Error>;
40
41 fn revoke(&self, command: &RevokeKeepsake) -> ProviderResult<Keepsake, Self::Error>;
43
44 fn active_for_subject(
46 &self,
47 subject: &SubjectRef,
48 ) -> ProviderResult<Vec<Keepsake>, Self::Error>;
49
50 fn get(&self, id: KeepsakeId) -> ProviderResult<Option<Keepsake>, Self::Error>;
52}
53
54pub trait ActiveRelationSource: Send + Sync {
60 type Error: Error + Send + Sync + 'static;
62
63 fn active_relations_for_subject<'a>(
65 &'a self,
66 subject: &'a SubjectRef,
67 ) -> impl Future<Output = ProviderResult<Vec<ActiveRelation>, Self::Error>> + Send + 'a;
68
69 fn active_relations_for_subject_by_ids<'a>(
71 &'a self,
72 subject: &'a SubjectRef,
73 relation_ids: &'a [RelationId],
74 ) -> impl Future<Output = ProviderResult<Vec<ActiveRelation>, Self::Error>> + Send + 'a;
75
76 fn active_relations_for_subject_by_keys<'a>(
78 &'a self,
79 subject: &'a SubjectRef,
80 keys: &'a [RelationKey],
81 ) -> impl Future<Output = ProviderResult<Vec<ActiveRelation>, Self::Error>> + Send + 'a;
82}
83
84pub type DynActiveRelationFuture<'a, E> =
86 Pin<Box<dyn Future<Output = ProviderResult<Vec<ActiveRelation>, E>> + Send + 'a>>;
87
88pub trait DynActiveRelationSource: Send + Sync {
94 type Error: Error + Send + Sync + 'static;
96
97 fn active_relations_for_subject<'a>(
99 &'a self,
100 subject: &'a SubjectRef,
101 ) -> DynActiveRelationFuture<'a, Self::Error>;
102
103 fn active_relations_for_subject_by_ids<'a>(
105 &'a self,
106 subject: &'a SubjectRef,
107 relation_ids: &'a [RelationId],
108 ) -> DynActiveRelationFuture<'a, Self::Error>;
109
110 fn active_relations_for_subject_by_keys<'a>(
112 &'a self,
113 subject: &'a SubjectRef,
114 keys: &'a [RelationKey],
115 ) -> DynActiveRelationFuture<'a, Self::Error>;
116}
117
118impl<T> DynActiveRelationSource for T
119where
120 T: ActiveRelationSource,
121{
122 type Error = T::Error;
123
124 fn active_relations_for_subject<'a>(
125 &'a self,
126 subject: &'a SubjectRef,
127 ) -> DynActiveRelationFuture<'a, Self::Error> {
128 Box::pin(ActiveRelationSource::active_relations_for_subject(
129 self, subject,
130 ))
131 }
132
133 fn active_relations_for_subject_by_ids<'a>(
134 &'a self,
135 subject: &'a SubjectRef,
136 relation_ids: &'a [RelationId],
137 ) -> DynActiveRelationFuture<'a, Self::Error> {
138 Box::pin(ActiveRelationSource::active_relations_for_subject_by_ids(
139 self,
140 subject,
141 relation_ids,
142 ))
143 }
144
145 fn active_relations_for_subject_by_keys<'a>(
146 &'a self,
147 subject: &'a SubjectRef,
148 keys: &'a [RelationKey],
149 ) -> DynActiveRelationFuture<'a, Self::Error> {
150 Box::pin(ActiveRelationSource::active_relations_for_subject_by_keys(
151 self, subject, keys,
152 ))
153 }
154}