1use async_trait::async_trait;
2use std::sync::Arc;
3
4use super::state::{State, StateConfig};
5use super::transaction::Transaction;
6
7#[async_trait]
10pub trait PluginTrait: Send + Sync + Debug {
11 async fn append_transaction(
14 &self,
15 _: &Transaction,
16 _: &State,
17 _: &State,
18 ) -> Option<Transaction> {
19 None
20 }
21 async fn filter_transaction(
24 &self,
25 _: &Transaction,
26 _: &State,
27 ) -> bool {
28 true
29 }
30
31 async fn before_apply_transaction(
33 &self,
34 _tr: &mut Transaction,
35 _state: &State,
36 ) -> Result<(), Box<dyn std::error::Error>> {
37 Ok(())
38 }
39
40 async fn after_apply_transaction(
42 &self,
43 _new_state: &State,
44 _tr: &mut Transaction,
45 _old_state: &State,
46 ) -> Result<(), Box<dyn std::error::Error>> {
47 Ok(())
48 }
49}
50#[async_trait]
53pub trait StateField: Send + Sync + Debug {
54 async fn init(
56 &self,
57 config: &StateConfig,
58 instance: Option<&State>,
59 ) -> PluginState;
60 async fn apply(
63 &self,
64 tr: &Transaction,
65 value: PluginState,
66 old_state: &State,
67 new_state: &State,
68 ) -> PluginState;
69 fn serialize(
71 &self,
72 _value: PluginState,
73 ) -> Option<Vec<u8>> {
74 None
75 }
76 fn deserialize(
78 &self,
79 _value: &Vec<u8>,
80 ) -> Option<PluginState> {
81 None
82 }
83}
84#[derive(Clone, Debug)]
87pub struct PluginSpec {
88 pub state: Option<Arc<dyn StateField>>,
89 pub key: PluginKey,
90 pub tr: Option<Arc<dyn PluginTrait>>,
91}
92impl PluginSpec {
93 async fn filter_transaction(
95 &self,
96 tr: &Transaction,
97 state: &State,
98 ) -> bool {
99 match &self.tr {
100 Some(filter) => filter.filter_transaction(tr, state).await,
101 None => false,
102 }
103 }
104 async fn append_transaction<'a>(
106 &self,
107 trs: &Transaction,
108 old_state: &State,
109 new_state: &State,
110 ) -> Option<Transaction> {
111 match &self.tr {
112 Some(transaction) => transaction.append_transaction(trs, old_state, new_state).await,
113 None => None,
114 }
115 }
116 pub async fn before_apply_transaction(
117 &self,
118 tr: &mut Transaction,
119 state: &State,
120 ) -> Result<(), Box<dyn std::error::Error>> {
121 if let Some(transaction) = &self.tr {
123 transaction.before_apply_transaction(tr, state).await?;
124 }
125 Ok(())
126 }
127
128 pub async fn after_apply_transaction(
130 &self,
131 new_state: &State,
132 tr: &mut Transaction,
133 old_state: &State,
134 ) -> Result<(), Box<dyn std::error::Error>> {
135 if let Some(transaction) = &self.tr {
137 transaction.after_apply_transaction(new_state, tr, old_state).await?;
138 }
139 Ok(())
140 }
141}
142#[derive(Clone, Debug)]
145pub struct Plugin {
146 pub spec: PluginSpec,
147 pub key: String,
148}
149
150impl Plugin {
151 pub fn new(spec: PluginSpec) -> Self {
153 let key = spec.key.0.clone();
154
155 Plugin { spec, key }
156 }
157
158 pub fn get_state(
160 &self,
161 state: &State,
162 ) -> Option<PluginState> {
163 state.get_field(&self.key)
164 }
165 pub async fn apply_filter_transaction(
167 &self,
168 tr: &Transaction,
169 state: &State,
170 ) -> bool {
171 self.spec.filter_transaction(tr, state).await
172 }
173
174 pub async fn before_apply_transaction(
176 &self,
177 tr: &mut Transaction,
178 state: &State,
179 ) -> Result<(), Box<dyn std::error::Error>> {
180 self.spec.before_apply_transaction(tr, state).await?;
182 Ok(())
183 }
184
185 pub async fn after_apply_transaction(
187 &self,
188 new_state: &State,
189 tr: &mut Transaction,
190 old_state: &State,
191 ) -> Result<(), Box<dyn std::error::Error>> {
192 self.spec.after_apply_transaction(new_state, tr, old_state).await?;
194 Ok(())
195 }
196
197 pub async fn apply_append_transaction(
199 &self,
200 trs: &Transaction,
201 old_state: &State,
202 new_state: &State,
203 ) -> Option<Transaction> {
204 self.spec.append_transaction(trs, old_state, new_state).await
205 }
206}
207
208pub type PluginState = Arc<dyn std::any::Any + Send + Sync>;
211
212use std::fmt::Debug;
213
214pub type PluginKey = (String, String);