context_weaver/core/processors/
plugin.rs

1use std::sync::Arc;
2
3use crate::{WorldInfoNode, WorldInfoProcessor};
4
5use super::{WorldInfoProcessorFactory, PluginBridge};
6
7/// Processor for loading plugins
8/// 
9/// Plugin Processors contain a reference to the ID of a plugin, aswell as the name of a callback function expected to return a string
10/// 
11/// Plugin Processors will have an identifier following this format: `weaver.plugin.<plugin_author>.<plugin_name>`
12
13#[derive(Clone, Debug)]
14pub struct PluginProcessor<'a, P: PluginBridge + 'a> {
15    plugin_id: P::PluginId,
16    plugin_name: String,
17    plugin_author: String,
18    plugin_data: serde_json::Value,
19    plugin_bridge: Arc<P>,
20    _marker: std::marker::PhantomData<&'a ()>
21}
22
23impl<'a, P: PluginBridge + 'a> WorldInfoNode for PluginProcessor<'a, P> {
24    fn content(&self) -> Result<String, crate::WorldInfoError> {
25        self.process()
26    }
27
28    fn name(&self) -> String {
29        format!("weaver.plugin.{}.{}", self.plugin_author, self.plugin_name)
30    }
31
32    fn cloned(&self) -> Box<dyn WorldInfoNode + 'a> {
33        Box::new(Clone::clone(self))
34    }
35}
36
37impl<'a, P: PluginBridge> WorldInfoProcessor for PluginProcessor<'a, P> {
38    fn process(&self) -> Result<String, crate::WorldInfoError> {
39        self.plugin_bridge.invoke_plugin(self.plugin_id, self.plugin_data.clone())
40    }
41}
42
43pub struct PluginProcessorFactory;
44
45impl<P: PluginBridge + 'static> WorldInfoProcessorFactory<P> for PluginProcessorFactory {
46    fn create(&self, properties: &serde_json::Value, bridge: &Arc<P>) -> Box<dyn WorldInfoProcessor> {
47        // parse out your plugin_id, name, author, props…
48        let plugin_id     = serde_json::from_value::<P::PluginId>(properties["plugin_id"].clone()).unwrap();
49        let plugin_name   = properties["plugin_name"].as_str().unwrap().to_string();
50        let plugin_author = properties["plugin_author"].as_str().unwrap().to_string();
51        let inner_props   = properties["plugin_data"].clone();
52
53        // cheaply clone the Arc handle
54        let bridge_handle = Arc::clone(bridge);
55
56        Box::new(PluginProcessor {
57            plugin_id,
58            plugin_name,
59            plugin_author,
60            plugin_data: inner_props,
61            plugin_bridge: bridge_handle,
62            _marker: std::marker::PhantomData
63        })
64    }
65}