1use core::fmt;
7
8use aranya_buggy::Bug;
9use serde::{Deserialize, Serialize};
10
11use crate::{
12 command::{Command, CommandId},
13 storage::{FactPerspective, Perspective},
14 Address,
15};
16
17#[derive(Debug, PartialEq, Eq)]
19pub enum EngineError {
20 Read,
21 Write,
22 Check,
23 Panic,
24 InternalError,
25 Bug(Bug),
26}
27
28impl fmt::Display for EngineError {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 Self::Read => write!(f, "read error"),
32 Self::Write => write!(f, "write error "),
33 Self::Check => write!(f, "check error"),
34 Self::Panic => write!(f, "panic"),
35 Self::InternalError => write!(f, "internal error"),
36 Self::Bug(b) => write!(f, "{b}"),
37 }
38 }
39}
40
41impl From<Bug> for EngineError {
42 fn from(value: Bug) -> Self {
43 EngineError::Bug(value)
44 }
45}
46
47impl core::error::Error for EngineError {}
48
49#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
50pub struct PolicyId(usize);
51
52impl PolicyId {
53 pub fn new(id: usize) -> Self {
54 PolicyId(id)
55 }
56}
57
58pub trait Engine {
60 type Policy: Policy<Effect = Self::Effect>;
61
62 type Effect;
63
64 fn add_policy(&mut self, policy: &[u8]) -> Result<PolicyId, EngineError>;
70
71 fn get_policy(&self, id: PolicyId) -> Result<&Self::Policy, EngineError>;
77}
78
79pub trait Sink<E> {
81 fn begin(&mut self);
82 fn consume(&mut self, effect: E);
83 fn rollback(&mut self);
84 fn commit(&mut self);
85}
86
87pub struct NullSink;
88
89impl<E> Sink<E> for NullSink {
90 fn begin(&mut self) {}
91
92 fn consume(&mut self, _effect: E) {}
93
94 fn rollback(&mut self) {}
95
96 fn commit(&mut self) {}
97}
98
99pub struct MergeIds {
101 left: Address,
103 right: Address,
104}
105
106impl MergeIds {
107 pub fn new(a: Address, b: Address) -> Option<Self> {
109 use core::cmp::Ordering;
110 match a.id.cmp(&b.id) {
111 Ordering::Less => Some(Self { left: a, right: b }),
112 Ordering::Equal => None,
113 Ordering::Greater => Some(Self { left: b, right: a }),
114 }
115 }
116}
117
118impl From<MergeIds> for (CommandId, CommandId) {
119 fn from(value: MergeIds) -> Self {
121 (value.left.id, value.right.id)
122 }
123}
124
125impl From<MergeIds> for (Address, Address) {
126 fn from(value: MergeIds) -> Self {
128 (value.left, value.right)
129 }
130}
131
132pub enum CommandRecall {
134 None,
136 OnCheck,
138}
139
140pub trait Policy {
143 type Action<'a>;
144 type Effect;
145 type Command<'a>: Command;
146
147 fn serial(&self) -> u32;
150
151 fn call_rule(
155 &self,
156 command: &impl Command,
157 facts: &mut impl FactPerspective,
158 sink: &mut impl Sink<Self::Effect>,
159 recall: CommandRecall,
160 ) -> Result<(), EngineError>;
161
162 fn call_action(
166 &self,
167 action: Self::Action<'_>,
168 facts: &mut impl Perspective,
169 sink: &mut impl Sink<Self::Effect>,
170 ) -> Result<(), EngineError>;
171
172 fn merge<'a>(
175 &self,
176 target: &'a mut [u8],
177 ids: MergeIds,
178 ) -> Result<Self::Command<'a>, EngineError>;
179}