use serde::{Deserialize, Serialize};
use toml;
use crate::{stream::StreamConfig, Error};
#[derive(Debug, Clone, Copy)]
pub enum ConfigFormat {
YAML,
JSON,
TOML,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoggingConfig {
pub level: String,
pub file_output: Option<bool>,
pub file_path: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EngineConfig {
pub streams: Vec<StreamConfig>,
pub http: Option<HttpServerConfig>,
pub metrics: Option<MetricsConfig>,
pub logging: Option<LoggingConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HttpServerConfig {
pub address: String,
pub cors_enabled: bool,
pub health_enabled: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetricsConfig {
pub enabled: bool,
pub type_name: String,
pub prefix: Option<String>,
pub tags: Option<std::collections::HashMap<String, String>>,
}
impl EngineConfig {
pub fn from_file(path: &str) -> Result<Self, Error> {
let content = std::fs::read_to_string(path)
.map_err(|e| Error::Config(format!("无法读取配置文件: {}", e)))?;
if let Some(format) = get_format_from_path(path) {
match format {
ConfigFormat::YAML => {
return serde_yaml::from_str(&content)
.map_err(|e| Error::Config(format!("YAML解析错误: {}", e)));
}
ConfigFormat::JSON => {
return serde_json::from_str(&content)
.map_err(|e| Error::Config(format!("JSON解析错误: {}", e)));
}
ConfigFormat::TOML => {
return toml::from_str(&content)
.map_err(|e| Error::Config(format!("TOML解析错误: {}", e)));
}
}
}
Self::from_string(&content)
}
pub fn from_string(content: &str) -> Result<Self, Error> {
if let Ok(config) = serde_yaml::from_str(content) {
return Ok(config);
}
if let Ok(config) = toml::from_str(content) {
return Ok(config);
}
if let Ok(config) = serde_json::from_str(content) {
return Ok(config);
}
Err(Error::Config(format!(
"无法解析配置文件,支持的格式为:YAML、TOML、JSON"
)))
}
pub fn save_to_file(&self, path: &str) -> Result<(), Error> {
let content = toml::to_string_pretty(self)
.map_err(|e| Error::Config(format!("无法序列化配置: {}", e)))?;
std::fs::write(path, content).map_err(|e| Error::Config(format!("无法写入配置文件: {}", e)))
}
}
pub fn default_config() -> EngineConfig {
EngineConfig {
streams: vec![],
http: Some(HttpServerConfig {
address: "0.0.0.0:8000".to_string(),
cors_enabled: false,
health_enabled: true,
}),
metrics: Some(MetricsConfig {
enabled: true,
type_name: "prometheus".to_string(),
prefix: Some("benthos".to_string()),
tags: None,
}),
logging: Some(LoggingConfig {
level: "info".to_string(),
file_output: None,
file_path: None,
}),
}
}
fn get_format_from_path(path: &str) -> Option<ConfigFormat> {
let path = path.to_lowercase();
if path.ends_with(".yaml") || path.ends_with(".yml") {
Some(ConfigFormat::YAML)
} else if path.ends_with(".json") {
Some(ConfigFormat::JSON)
} else if path.ends_with(".toml") {
Some(ConfigFormat::TOML)
} else {
None
}
}