pub mod types;
pub mod unified;
pub use crate::config::types::{FmtDirective, OtelDirective};
use crate::error::Result;
use types::APP_FOLDER;
pub use types::{CONFIG, Config, LogFormat, OtlpConfig};
pub use unified::{ApiConfig as UnifiedApiConfig, CliConfig, McpConfig, UnifiedConfig};
impl Config {
pub fn new() -> Self {
get_config().unwrap_or_default()
}
#[cfg(feature = "storage")]
pub fn get_storage_config(&self) -> crate::storage::StorageConfig {
let mut storage_config = self.storage.clone();
if let Ok(database_url) =
std::env::var("DATABASE_URL").or_else(|_| std::env::var("VKTEAMS_BOT_DATABASE_URL"))
{
storage_config.database.url = database_url;
}
storage_config
}
}
pub fn get_config() -> Result<Config> {
std::env::var(APP_FOLDER)
.map(std::fs::read_to_string)?
.map(|str| toml::from_str::<Config>(&str))?
.map_err(|e| e.into())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_new_default() {
let config = Config::new();
#[cfg(feature = "otlp")]
{
assert_eq!(config.otlp.instance_id, "bot");
}
assert_eq!(config.network.retries, 3);
}
#[test]
fn test_config_default_values() {
let config = Config::default();
assert_eq!(config.network.retries, 3);
assert_eq!(config.network.max_backoff_ms, 5000);
assert_eq!(config.network.request_timeout_secs, 30);
#[cfg(feature = "longpoll")]
{
assert_eq!(config.listener.empty_backoff_ms, 500);
assert_eq!(config.listener.max_events_per_batch, 50);
}
#[cfg(feature = "otlp")]
{
assert_eq!(config.otlp.instance_id, "bot");
assert_eq!(config.otlp.deployment_environment_name, "dev");
assert_eq!(config.otlp.exporter_endpoint, None);
assert_eq!(config.otlp.exporter_timeout, 0);
assert_eq!(config.otlp.exporter_metric_interval, 0);
assert_eq!(config.otlp.ratio, 1.0);
assert_eq!(config.otlp.otel_filter_default, "debug");
assert_eq!(config.otlp.fmt_filter_default, "debug");
assert_eq!(config.otlp.fmt_filter_self_directive, "debug");
assert_eq!(config.otlp.log_format, crate::config::LogFormat::Pretty);
assert!(config.otlp.fmt_ansi);
}
}
#[test]
fn test_config_import_types() {
let _config: Config = Config::default();
let _log_format: LogFormat = LogFormat::Pretty;
#[cfg(feature = "otlp")]
{
let _otlp_config: OtlpConfig = OtlpConfig::default();
}
}
#[cfg(feature = "storage")]
#[test]
fn test_get_storage_config() {
let config = Config::default();
let storage_config = config.get_storage_config();
assert_eq!(storage_config.database.max_connections, 20);
assert!(storage_config.database.auto_migrate);
assert_eq!(storage_config.settings.event_retention_days, 365);
}
#[cfg(feature = "storage")]
#[test]
fn test_get_storage_config_basic() {
let config = Config::default();
let storage_config = config.get_storage_config();
assert_eq!(storage_config.database.max_connections, 20);
assert!(storage_config.database.auto_migrate);
assert_eq!(storage_config.settings.event_retention_days, 365);
assert_eq!(
storage_config.database.url,
"postgresql://localhost/vkteams_bot"
);
}
}