1use std::collections::HashMap;
6use std::path::PathBuf;
7use std::sync::{Arc, RwLock};
8
9pub trait PluginConfigAPI: Send + Sync {
11 fn get(&self, key: &str) -> Option<serde_json::Value>;
13 fn set(&self, key: &str, value: serde_json::Value);
15 fn get_all(&self) -> HashMap<String, serde_json::Value>;
17 fn has(&self, key: &str) -> bool;
19 fn delete(&self, key: &str);
21}
22
23pub trait PluginLogger: Send + Sync {
25 fn debug(&self, message: &str);
26 fn info(&self, message: &str);
27 fn warn(&self, message: &str);
28 fn error(&self, message: &str);
29}
30
31pub struct DefaultConfigAPI {
33 config: Arc<RwLock<HashMap<String, serde_json::Value>>>,
34}
35
36impl DefaultConfigAPI {
37 pub fn new() -> Self {
38 Self {
39 config: Arc::new(RwLock::new(HashMap::new())),
40 }
41 }
42}
43
44impl Default for DefaultConfigAPI {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50impl PluginConfigAPI for DefaultConfigAPI {
51 fn get(&self, key: &str) -> Option<serde_json::Value> {
52 self.config.read().ok()?.get(key).cloned()
53 }
54
55 fn set(&self, key: &str, value: serde_json::Value) {
56 if let Ok(mut config) = self.config.write() {
57 config.insert(key.to_string(), value);
58 }
59 }
60
61 fn get_all(&self) -> HashMap<String, serde_json::Value> {
62 self.config.read().map(|c| c.clone()).unwrap_or_default()
63 }
64
65 fn has(&self, key: &str) -> bool {
66 self.config
67 .read()
68 .map(|c| c.contains_key(key))
69 .unwrap_or(false)
70 }
71
72 fn delete(&self, key: &str) {
73 if let Ok(mut config) = self.config.write() {
74 config.remove(key);
75 }
76 }
77}
78
79pub struct DefaultLogger {
81 plugin_name: String,
82}
83
84impl DefaultLogger {
85 pub fn new(plugin_name: &str) -> Self {
86 Self {
87 plugin_name: plugin_name.to_string(),
88 }
89 }
90}
91
92impl PluginLogger for DefaultLogger {
93 fn debug(&self, message: &str) {
94 tracing::debug!("[Plugin:{}] {}", self.plugin_name, message);
95 }
96
97 fn info(&self, message: &str) {
98 tracing::info!("[Plugin:{}] {}", self.plugin_name, message);
99 }
100
101 fn warn(&self, message: &str) {
102 tracing::warn!("[Plugin:{}] {}", self.plugin_name, message);
103 }
104
105 fn error(&self, message: &str) {
106 tracing::error!("[Plugin:{}] {}", self.plugin_name, message);
107 }
108}
109
110pub struct PluginContext {
112 pub plugin_name: String,
114 pub plugin_path: PathBuf,
116 pub config: Box<dyn PluginConfigAPI>,
118 pub logger: Box<dyn PluginLogger>,
120}
121
122impl PluginContext {
123 pub fn new(plugin_name: &str, plugin_path: PathBuf) -> Self {
125 Self {
126 plugin_name: plugin_name.to_string(),
127 plugin_path,
128 config: Box::new(DefaultConfigAPI::new()),
129 logger: Box::new(DefaultLogger::new(plugin_name)),
130 }
131 }
132}