use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::{Arc, RwLock};
use anyhow::anyhow;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::generators::GeneratorTestMode;
use crate::json_utils::json_deep_merge;
use crate::path_exp::DocPath;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct PluginData {
pub name: String,
pub version: String,
#[serde(default)]
pub configuration: HashMap<String, Value>
}
impl PluginData {
pub fn merge(&mut self, data: &HashMap<String, Value>) {
for (key, value) in data {
let value = if let Some(v) = self.configuration.get(key) {
json_deep_merge(v, value)
} else {
value.clone()
};
self.configuration.insert(key.clone(), value);
}
}
}
impl PluginData {
pub fn to_json(&self) -> anyhow::Result<Value> {
serde_json::to_value(self)
.map_err(|err| anyhow!("Could not convert plugin data to JSON - {}", err))
}
}
pub trait PluginSupport: Debug + Send + Sync {
fn config_key(&self, rule_name: &str) -> Option<String>;
fn generate(
&self,
name: &str,
values: &Value,
example: &Value,
mode: Option<GeneratorTestMode>,
path: &DocPath,
context: &HashMap<&str, Value>
) -> anyhow::Result<Value>;
}
lazy_static! {
static ref PLUGIN_SUPPORT: RwLock<Option<Arc<dyn PluginSupport>>> = RwLock::new(None);
}
pub fn set_plugin_support(support: Arc<dyn PluginSupport>) {
let mut guard = PLUGIN_SUPPORT.write().unwrap();
*guard = Some(support);
}
pub fn plugin_support() -> Option<Arc<dyn PluginSupport>> {
PLUGIN_SUPPORT.read().unwrap().clone()
}
pub fn plugin_rule_config_key(rule_name: &str) -> String {
plugin_support()
.and_then(|support| support.config_key(rule_name))
.unwrap_or_else(|| "value".to_string())
}