moduforge_state/
plugin.rs1use async_trait::async_trait;
2use std::sync::Arc;
3
4use crate::error::StateResult;
5use crate::resource::Resource;
6
7use super::state::{State, StateConfig};
8use super::transaction::Transaction;
9
10#[async_trait]
13pub trait PluginTrait: Send + Sync + Debug {
14 async fn append_transaction(
17 &self,
18 _: &[Transaction],
19 _: &State,
20 _: &State,
21 ) -> StateResult<Option<Transaction>> {
22 Ok(None)
23 }
24 async fn filter_transaction(
27 &self,
28 _: &Transaction,
29 _: &State,
30 ) -> bool {
31 true
32 }
33}
34#[async_trait]
37pub trait StateField: Send + Sync + Debug {
38 async fn init(
40 &self,
41 config: &StateConfig,
42 instance: Option<&State>,
43 ) -> Arc<dyn Resource>;
44 async fn apply(
47 &self,
48 tr: &Transaction,
49 value: Arc<dyn Resource>,
50 old_state: &State,
51 new_state: &State,
52 ) -> Arc<dyn Resource>;
53 fn serialize(
55 &self,
56 _value: Arc<dyn Resource>,
57 ) -> Option<Vec<u8>> {
58 None
59 }
60 fn deserialize(
62 &self,
63 _value: &Vec<u8>,
64 ) -> Option<Arc<dyn Resource>> {
65 None
66 }
67}
68#[derive(Clone, Debug)]
71pub struct PluginSpec {
72 pub state_field: Option<Arc<dyn StateField>>,
73 pub key: PluginKey,
74 pub tr: Option<Arc<dyn PluginTrait>>,
75 pub priority: i32,
76}
77
78unsafe impl Send for PluginSpec {}
79unsafe impl Sync for PluginSpec {}
80
81impl PluginSpec {
82 async fn filter_transaction(
84 &self,
85 tr: &Transaction,
86 state: &State,
87 ) -> bool {
88 match &self.tr {
89 Some(filter) => filter.filter_transaction(tr, state).await,
90 None => false,
91 }
92 }
93 async fn append_transaction<'a>(
95 &self,
96 trs: &'a [Transaction],
97 old_state: &State,
98 new_state: &State,
99 ) -> StateResult<Option<Transaction>> {
100 match &self.tr {
101 Some(transaction) => {
102 let tr = transaction
103 .append_transaction(trs, old_state, new_state)
104 .await?;
105 if let Some(mut tr) = tr {
106 tr.commit();
107 Ok(Some(tr))
108 } else {
109 Ok(None)
110 }
111 },
112 None => Ok(None),
113 }
114 }
115}
116#[derive(Clone, Debug)]
119pub struct Plugin {
120 pub spec: PluginSpec,
121 pub key: String,
122}
123
124unsafe impl Send for Plugin {}
125unsafe impl Sync for Plugin {}
126
127impl Plugin {
128 pub fn new(spec: PluginSpec) -> Self {
130 let key = spec.key.0.clone();
131
132 Plugin { spec, key }
133 }
134
135 pub fn get_state(
137 &self,
138 state: &State,
139 ) -> Option<Arc<dyn Resource>> {
140 state.get_field(&self.key)
141 }
142 pub async fn apply_filter_transaction(
144 &self,
145 tr: &Transaction,
146 state: &State,
147 ) -> bool {
148 self.spec.filter_transaction(tr, state).await
149 }
150
151 pub async fn apply_append_transaction(
153 &self,
154 trs: &[Transaction],
155 old_state: &State,
156 new_state: &State,
157 ) -> StateResult<Option<Transaction>> {
158 self.spec.append_transaction(trs, old_state, new_state).await
159 }
160}
161
162use std::fmt::Debug;
166
167pub type PluginKey = (String, String);