use serde::{Deserialize, Serialize};
use serde_yaml::{Mapping, Value};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub tag: Option<String>,
#[serde(rename = "type", alias = "plugin_type")]
pub plugin_type: String,
#[serde(default)]
pub args: serde_yaml::Value,
#[serde(
default = "default_priority",
skip_serializing_if = "is_default_priority"
)]
pub priority: i32,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub config: HashMap<String, serde_yaml::Value>,
}
fn default_priority() -> i32 {
100
}
fn is_default_priority(priority: &i32) -> bool {
*priority == 100
}
impl PluginConfig {
pub fn new(plugin_type: String) -> Self {
Self {
tag: None,
plugin_type,
args: Value::Mapping(Mapping::new()),
priority: default_priority(),
config: HashMap::new(),
}
}
pub fn with_tag(mut self, tag: String) -> Self {
self.tag = Some(tag);
self
}
pub fn with_priority(mut self, priority: i32) -> Self {
self.priority = priority;
self
}
pub fn with_arg(mut self, key: String, value: Value) -> Self {
if let Value::Mapping(ref mut map) = self.args {
map.insert(Value::String(key), value);
} else {
let mut map = Mapping::new();
map.insert(Value::String(key), value);
self.args = Value::Mapping(map);
}
self
}
pub fn with_config(mut self, key: String, value: serde_yaml::Value) -> Self {
self.config.insert(key, value);
self
}
pub fn effective_name(&self) -> &str {
self.tag.as_deref().unwrap_or(&self.plugin_type)
}
pub fn effective_args(&self) -> HashMap<String, Value> {
let mut result = self.config.clone();
if let Value::Mapping(map) = &self.args {
for (k, v) in map {
if let Value::String(key) = k {
result.insert(key.clone(), v.clone());
}
}
}
result
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_plugin_config_creation() {
let config = PluginConfig::new("forward".to_string());
assert_eq!(config.plugin_type, "forward");
assert_eq!(config.priority, 100);
}
#[test]
fn test_plugin_config_builder() {
let config = PluginConfig::new("forward".to_string())
.with_tag("my_forward".to_string())
.with_priority(50);
assert_eq!(config.effective_name(), "my_forward");
assert_eq!(config.priority, 50);
}
#[test]
fn test_plugin_effective_name() {
let config1 = PluginConfig::new("forward".to_string()).with_tag("forward".to_string());
assert_eq!(config1.effective_name(), "forward");
let config2 = PluginConfig::new("forward".to_string()).with_tag("my_forward".to_string());
assert_eq!(config2.effective_name(), "my_forward");
}
#[test]
fn test_plugin_config_with_values() {
let config = PluginConfig::new("forward".to_string()).with_config(
"upstream".to_string(),
serde_yaml::Value::String("8.8.8.8".to_string()),
);
assert!(config.config.contains_key("upstream"));
}
}