mf_state/plugin/
plugin.rs1use async_trait::async_trait;
2use std::sync::Arc;
3
4use crate::error::StateResult;
5use crate::plugin::{PluginConfig, PluginMetadata};
6use crate::resource::Resource;
7
8use crate::state::{State, StateConfig};
9use crate::transaction::Transaction;
10
11#[async_trait]
14pub trait PluginTrait: Send + Sync + Debug {
15 fn metadata(&self) -> PluginMetadata;
17
18 fn config(&self) -> PluginConfig {
20 PluginConfig {
21 enabled: true,
22 priority: 0,
23 settings: std::collections::HashMap::new(),
24 }
25 }
26
27 async fn append_transaction(
30 &self,
31 _: &[Arc<Transaction>],
32 _: &Arc<State>,
33 _: &Arc<State>,
34 ) -> StateResult<Option<Transaction>> {
35 Ok(None)
36 }
37 async fn filter_transaction(
40 &self,
41 _: &Transaction,
42 _: &State,
43 ) -> bool {
44 true
45 }
46}
47#[async_trait]
84pub trait StateField: Send + Sync + Debug {
85 type Value: Resource;
87
88 async fn init(
90 &self,
91 config: &StateConfig,
92 instance: &State,
93 ) -> Arc<Self::Value>;
94
95 async fn apply(
98 &self,
99 tr: &Transaction,
100 value: Arc<Self::Value>,
101 old_state: &State,
102 new_state: &State,
103 ) -> Arc<Self::Value>;
104
105 fn serialize(
107 &self,
108 _value: &Arc<Self::Value>,
109 ) -> Option<Vec<u8>> {
110 None
111 }
112
113 fn deserialize(
115 &self,
116 _data: &[u8],
117 ) -> Option<Arc<Self::Value>> {
118 None
119 }
120}
121
122#[async_trait]
125pub trait ErasedStateField: Send + Sync + Debug {
126 async fn init_erased(
128 &self,
129 config: &StateConfig,
130 instance: &State,
131 ) -> Arc<dyn Resource>;
132
133 async fn apply_erased(
135 &self,
136 tr: &Transaction,
137 value: Arc<dyn Resource>,
138 old_state: &State,
139 new_state: &State,
140 ) -> Arc<dyn Resource>;
141
142 fn serialize_erased(
144 &self,
145 value: Arc<dyn Resource>,
146 ) -> Option<Vec<u8>>;
147
148 fn deserialize_erased(
150 &self,
151 data: &[u8],
152 ) -> Option<Arc<dyn Resource>>;
153}
154
155#[async_trait]
157impl<T: StateField + 'static> ErasedStateField for T {
158 async fn init_erased(
159 &self,
160 config: &StateConfig,
161 instance: &State,
162 ) -> Arc<dyn Resource> {
163 let value = self.init(config, instance).await;
164 value as Arc<dyn Resource>
165 }
166
167 async fn apply_erased(
168 &self,
169 tr: &Transaction,
170 value: Arc<dyn Resource>,
171 old_state: &State,
172 new_state: &State,
173 ) -> Arc<dyn Resource> {
174 if let Some(typed_value) = value.downcast_arc::<T::Value>() {
176 let new_value =
177 self.apply(tr, typed_value.clone(), old_state, new_state).await;
178 new_value as Arc<dyn Resource>
179 } else {
180 tracing::warn!(
182 "StateField 类型不匹配,期望 {},跳过应用",
183 std::any::type_name::<T::Value>()
184 );
185 value
186 }
187 }
188
189 fn serialize_erased(
190 &self,
191 value: Arc<dyn Resource>,
192 ) -> Option<Vec<u8>> {
193 if let Some(typed_value) = value.downcast_arc::<T::Value>() {
194 self.serialize(typed_value)
195 } else {
196 None
197 }
198 }
199
200 fn deserialize_erased(
201 &self,
202 data: &[u8],
203 ) -> Option<Arc<dyn Resource>> {
204 self.deserialize(data).map(|v| v as Arc<dyn Resource>)
205 }
206}
207
208#[derive(Clone, Debug)]
211pub struct PluginSpec {
212 pub state_field: Option<Arc<dyn ErasedStateField>>,
213 pub tr: Arc<dyn PluginTrait>,
214}
215
216impl PluginSpec {
219 async fn filter_transaction(
221 &self,
222 tr: &Transaction,
223 state: &State,
224 ) -> bool {
225 let filter = &self.tr;
226 filter.filter_transaction(tr, state).await
227 }
228 async fn append_transaction(
230 &self,
231 trs: &[Arc<Transaction>],
232 old_state: &Arc<State>,
233 new_state: &Arc<State>,
234 ) -> StateResult<Option<Transaction>> {
235 let tr = self.tr.append_transaction(trs, old_state, new_state).await?;
236 if let Some(mut tr) = tr {
237 let _ = tr.commit(); Ok(Some(tr))
239 } else {
240 Ok(None)
241 }
242 }
243}
244#[derive(Clone, Debug)]
247pub struct Plugin {
248 pub spec: PluginSpec,
249 pub key: String,
250}
251
252impl Plugin {
255 pub fn new(spec: PluginSpec) -> Self {
257 let key = spec.tr.metadata().name.clone();
258
259 Plugin { spec, key }
260 }
261 pub fn get_name(&self) -> &str {
263 &self.key
264 }
265 pub fn get_metadata(&self) -> PluginMetadata {
267 self.spec.tr.metadata()
268 }
269 pub fn get_config(&self) -> PluginConfig {
271 self.spec.tr.config()
272 }
273
274 pub fn get_state(
276 &self,
277 state: &State,
278 ) -> Option<Arc<dyn Resource>> {
279 state.get_field(&self.key)
280 }
281 pub async fn apply_filter_transaction(
283 &self,
284 tr: &Transaction,
285 state: &State,
286 ) -> bool {
287 self.spec.filter_transaction(tr, state).await
288 }
289
290 pub async fn apply_append_transaction(
292 &self,
293 trs: &[Arc<Transaction>],
294 old_state: &Arc<State>,
295 new_state: &Arc<State>,
296 ) -> StateResult<Option<Transaction>> {
297 self.spec.append_transaction(trs, old_state, new_state).await
298 }
299}
300
301use std::fmt::Debug;