1use crate::{AdmissionResult, EffectResult, OperationAction};
2use bcx_core::{CapabilityRef, CheckpointId, PolicyId, StatementId, SubjectId, ValidationError};
3
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6pub enum StatementKind {
7 Intent,
9 Admission,
11 Effect,
13 Delegation,
15 Revocation,
17 Checkpoint,
19 Contradiction,
21}
22
23#[derive(Debug, Eq, PartialEq)]
25pub struct Intent {
26 statement_id: StatementId,
27 subject: SubjectId,
28 action: OperationAction,
29}
30
31impl Intent {
32 #[must_use]
34 pub const fn new(
35 statement_id: StatementId,
36 subject: SubjectId,
37 action: OperationAction,
38 ) -> Self {
39 Self {
40 statement_id,
41 subject,
42 action,
43 }
44 }
45
46 #[must_use]
48 pub const fn kind(&self) -> StatementKind {
49 StatementKind::Intent
50 }
51
52 #[must_use]
54 pub const fn statement_id(&self) -> &StatementId {
55 &self.statement_id
56 }
57
58 #[must_use]
60 pub const fn subject(&self) -> &SubjectId {
61 &self.subject
62 }
63
64 #[must_use]
66 pub const fn action(&self) -> OperationAction {
67 self.action
68 }
69}
70
71#[derive(Debug, Eq, PartialEq)]
73pub struct Admission {
74 statement_id: StatementId,
75 intent_id: StatementId,
76 policy_id: PolicyId,
77 result: AdmissionResult,
78}
79
80impl Admission {
81 pub fn new(
83 statement_id: StatementId,
84 intent_id: StatementId,
85 policy_id: PolicyId,
86 result: AdmissionResult,
87 ) -> Result<Self, ValidationError> {
88 ensure_distinct(&statement_id, &intent_id)?;
89 Ok(Self {
90 statement_id,
91 intent_id,
92 policy_id,
93 result,
94 })
95 }
96
97 #[must_use]
99 pub const fn kind(&self) -> StatementKind {
100 StatementKind::Admission
101 }
102
103 #[must_use]
105 pub const fn statement_id(&self) -> &StatementId {
106 &self.statement_id
107 }
108
109 #[must_use]
111 pub const fn intent_id(&self) -> &StatementId {
112 &self.intent_id
113 }
114
115 #[must_use]
117 pub const fn policy_id(&self) -> &PolicyId {
118 &self.policy_id
119 }
120
121 #[must_use]
123 pub const fn result(&self) -> AdmissionResult {
124 self.result
125 }
126}
127
128#[derive(Debug, Eq, PartialEq)]
130pub struct Effect {
131 statement_id: StatementId,
132 intent_id: StatementId,
133 result: EffectResult,
134}
135
136impl Effect {
137 pub fn new(
139 statement_id: StatementId,
140 intent_id: StatementId,
141 result: EffectResult,
142 ) -> Result<Self, ValidationError> {
143 ensure_distinct(&statement_id, &intent_id)?;
144 Ok(Self {
145 statement_id,
146 intent_id,
147 result,
148 })
149 }
150
151 #[must_use]
153 pub const fn kind(&self) -> StatementKind {
154 StatementKind::Effect
155 }
156
157 #[must_use]
159 pub const fn statement_id(&self) -> &StatementId {
160 &self.statement_id
161 }
162
163 #[must_use]
165 pub const fn intent_id(&self) -> &StatementId {
166 &self.intent_id
167 }
168
169 #[must_use]
171 pub const fn result(&self) -> EffectResult {
172 self.result
173 }
174}
175
176#[derive(Debug, Eq, PartialEq)]
178pub struct Delegation {
179 statement_id: StatementId,
180 from_subject: SubjectId,
181 to_subject: SubjectId,
182 capability: CapabilityRef,
183}
184
185impl Delegation {
186 pub fn new(
188 statement_id: StatementId,
189 from_subject: SubjectId,
190 to_subject: SubjectId,
191 capability: CapabilityRef,
192 ) -> Result<Self, ValidationError> {
193 if from_subject == to_subject {
194 return Err(ValidationError::Malformed);
195 }
196 Ok(Self {
197 statement_id,
198 from_subject,
199 to_subject,
200 capability,
201 })
202 }
203
204 #[must_use]
206 pub const fn kind(&self) -> StatementKind {
207 StatementKind::Delegation
208 }
209
210 #[must_use]
212 pub const fn statement_id(&self) -> &StatementId {
213 &self.statement_id
214 }
215
216 #[must_use]
218 pub const fn from_subject(&self) -> &SubjectId {
219 &self.from_subject
220 }
221
222 #[must_use]
224 pub const fn to_subject(&self) -> &SubjectId {
225 &self.to_subject
226 }
227
228 #[must_use]
230 pub const fn capability(&self) -> CapabilityRef {
231 self.capability
232 }
233}
234
235#[derive(Debug, Eq, PartialEq)]
237pub struct Revocation {
238 statement_id: StatementId,
239 target_id: StatementId,
240 authority: CapabilityRef,
241}
242
243impl Revocation {
244 pub fn new(
246 statement_id: StatementId,
247 target_id: StatementId,
248 authority: CapabilityRef,
249 ) -> Result<Self, ValidationError> {
250 ensure_distinct(&statement_id, &target_id)?;
251 Ok(Self {
252 statement_id,
253 target_id,
254 authority,
255 })
256 }
257
258 #[must_use]
260 pub const fn kind(&self) -> StatementKind {
261 StatementKind::Revocation
262 }
263
264 #[must_use]
266 pub const fn statement_id(&self) -> &StatementId {
267 &self.statement_id
268 }
269
270 #[must_use]
272 pub const fn target_id(&self) -> &StatementId {
273 &self.target_id
274 }
275
276 #[must_use]
278 pub const fn authority(&self) -> CapabilityRef {
279 self.authority
280 }
281}
282
283#[derive(Debug, Eq, PartialEq)]
285pub struct Checkpoint {
286 statement_id: StatementId,
287 checkpoint_id: CheckpointId,
288 subject: SubjectId,
289}
290
291impl Checkpoint {
292 #[must_use]
294 pub const fn new(
295 statement_id: StatementId,
296 checkpoint_id: CheckpointId,
297 subject: SubjectId,
298 ) -> Self {
299 Self {
300 statement_id,
301 checkpoint_id,
302 subject,
303 }
304 }
305
306 #[must_use]
308 pub const fn kind(&self) -> StatementKind {
309 StatementKind::Checkpoint
310 }
311
312 #[must_use]
314 pub const fn statement_id(&self) -> &StatementId {
315 &self.statement_id
316 }
317
318 #[must_use]
320 pub const fn checkpoint_id(&self) -> &CheckpointId {
321 &self.checkpoint_id
322 }
323
324 #[must_use]
326 pub const fn subject(&self) -> &SubjectId {
327 &self.subject
328 }
329}
330
331#[derive(Debug, Eq, PartialEq)]
333pub struct Contradiction {
334 statement_id: StatementId,
335 disputed_id: StatementId,
336 contradicts_id: StatementId,
337}
338
339impl Contradiction {
340 pub fn new(
342 statement_id: StatementId,
343 disputed_id: StatementId,
344 contradicts_id: StatementId,
345 ) -> Result<Self, ValidationError> {
346 ensure_distinct(&statement_id, &disputed_id)?;
347 ensure_distinct(&statement_id, &contradicts_id)?;
348 ensure_distinct(&disputed_id, &contradicts_id)?;
349 Ok(Self {
350 statement_id,
351 disputed_id,
352 contradicts_id,
353 })
354 }
355
356 #[must_use]
358 pub const fn kind(&self) -> StatementKind {
359 StatementKind::Contradiction
360 }
361
362 #[must_use]
364 pub const fn statement_id(&self) -> &StatementId {
365 &self.statement_id
366 }
367
368 #[must_use]
370 pub const fn disputed_id(&self) -> &StatementId {
371 &self.disputed_id
372 }
373
374 #[must_use]
376 pub const fn contradicts_id(&self) -> &StatementId {
377 &self.contradicts_id
378 }
379}
380
381fn ensure_distinct(left: &StatementId, right: &StatementId) -> Result<(), ValidationError> {
382 if left == right {
383 Err(ValidationError::Malformed)
384 } else {
385 Ok(())
386 }
387}