1use std::future::Future;
2use std::pin::Pin;
3
4use tea_policy::{ActorId, PolicyGrant};
5use tea_protocol::{RecordEnvelope, SessionId, SessionSequence};
6
7use crate::{
8 ApprovalArtifactEntry, GrantJournalEntry, MaterializedSessionState, SessionStoreError,
9};
10
11pub type SessionStoreFuture<'a, T> =
13 Pin<Box<dyn Future<Output = Result<T, SessionStoreError>> + Send + 'a>>;
14
15#[derive(Debug, Clone)]
17pub struct AppendTransaction {
18 session_id: SessionId,
19 expected_sequence: Option<SessionSequence>,
20 records: Vec<RecordEnvelope>,
21 expected_journal_revision: Option<u64>,
22 approval_artifacts: Vec<ApprovalArtifactEntry>,
23 grant_entries: Vec<GrantJournalEntry>,
24}
25
26impl AppendTransaction {
27 #[must_use]
29 pub fn new(
30 session_id: SessionId,
31 expected_sequence: Option<SessionSequence>,
32 records: Vec<RecordEnvelope>,
33 ) -> Self {
34 Self {
35 session_id,
36 expected_sequence,
37 records,
38 expected_journal_revision: None,
39 approval_artifacts: Vec::new(),
40 grant_entries: Vec::new(),
41 }
42 }
43
44 #[must_use]
46 pub const fn with_expected_journal_revision(mut self, revision: u64) -> Self {
47 self.expected_journal_revision = Some(revision);
48 self
49 }
50
51 #[must_use]
53 pub fn with_approval_artifacts(
54 mut self,
55 entries: impl IntoIterator<Item = ApprovalArtifactEntry>,
56 ) -> Self {
57 self.approval_artifacts = entries.into_iter().collect();
58 self
59 }
60
61 #[must_use]
63 pub fn with_grant_entries(
64 mut self,
65 entries: impl IntoIterator<Item = GrantJournalEntry>,
66 ) -> Self {
67 self.grant_entries = entries.into_iter().collect();
68 self
69 }
70
71 #[must_use]
73 pub const fn session_id(&self) -> SessionId {
74 self.session_id
75 }
76
77 #[must_use]
79 pub const fn expected_sequence(&self) -> Option<SessionSequence> {
80 self.expected_sequence
81 }
82
83 #[must_use]
85 pub fn records(&self) -> &[RecordEnvelope] {
86 &self.records
87 }
88
89 #[must_use]
91 pub const fn expected_journal_revision(&self) -> Option<u64> {
92 self.expected_journal_revision
93 }
94
95 #[must_use]
97 pub fn approval_artifacts(&self) -> &[ApprovalArtifactEntry] {
98 &self.approval_artifacts
99 }
100
101 #[must_use]
103 pub fn grant_entries(&self) -> &[GrantJournalEntry] {
104 &self.grant_entries
105 }
106}
107
108#[derive(Debug, Clone, PartialEq)]
110pub struct AppendOutcome {
111 previous_sequence: Option<SessionSequence>,
112 current_sequence: SessionSequence,
113 state: MaterializedSessionState,
114 journal_revision: u64,
115}
116
117impl AppendOutcome {
118 pub(crate) const fn new(
119 previous_sequence: Option<SessionSequence>,
120 current_sequence: SessionSequence,
121 state: MaterializedSessionState,
122 journal_revision: u64,
123 ) -> Self {
124 Self {
125 previous_sequence,
126 current_sequence,
127 state,
128 journal_revision,
129 }
130 }
131
132 #[must_use]
134 pub const fn previous_sequence(&self) -> Option<SessionSequence> {
135 self.previous_sequence
136 }
137
138 #[must_use]
140 pub const fn current_sequence(&self) -> SessionSequence {
141 self.current_sequence
142 }
143
144 #[must_use]
146 pub const fn journal_revision(&self) -> u64 {
147 self.journal_revision
148 }
149
150 #[must_use]
152 pub const fn state(&self) -> &MaterializedSessionState {
153 &self.state
154 }
155}
156
157#[derive(Debug, Clone, PartialEq)]
159pub struct SessionSnapshot {
160 records: Vec<RecordEnvelope>,
161 state: MaterializedSessionState,
162 approval_artifacts: Vec<ApprovalArtifactEntry>,
163 grant_journal: Vec<GrantJournalEntry>,
164 active_grants: Vec<PolicyGrant>,
165 journal_revision: u64,
166}
167
168impl SessionSnapshot {
169 pub(crate) const fn new(
170 records: Vec<RecordEnvelope>,
171 state: MaterializedSessionState,
172 approval_artifacts: Vec<ApprovalArtifactEntry>,
173 grant_journal: Vec<GrantJournalEntry>,
174 active_grants: Vec<PolicyGrant>,
175 journal_revision: u64,
176 ) -> Self {
177 Self {
178 records,
179 state,
180 approval_artifacts,
181 grant_journal,
182 active_grants,
183 journal_revision,
184 }
185 }
186
187 #[must_use]
189 pub fn records(&self) -> &[RecordEnvelope] {
190 &self.records
191 }
192
193 #[must_use]
195 pub const fn state(&self) -> &MaterializedSessionState {
196 &self.state
197 }
198
199 #[must_use]
201 pub fn approval_artifacts(&self) -> &[ApprovalArtifactEntry] {
202 &self.approval_artifacts
203 }
204
205 #[must_use]
207 pub fn grant_journal(&self) -> &[GrantJournalEntry] {
208 &self.grant_journal
209 }
210
211 #[must_use]
213 pub const fn journal_revision(&self) -> u64 {
214 self.journal_revision
215 }
216
217 #[must_use]
219 pub fn active_grants(&self) -> &[PolicyGrant] {
220 &self.active_grants
221 }
222}
223
224pub trait SessionStore: std::fmt::Debug + Send + Sync {
226 fn load(&self, session_id: SessionId) -> SessionStoreFuture<'_, SessionSnapshot>;
228
229 fn append(&self, transaction: AppendTransaction) -> SessionStoreFuture<'_, AppendOutcome>;
231
232 fn active_grants_for_actor(
234 &self,
235 actor_id: ActorId,
236 ) -> SessionStoreFuture<'_, Vec<PolicyGrant>>;
237}