use serde::{Deserialize, Serialize};
use crate::{Result, BuilderError};
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CalculatorConfig {
#[serde(default = "default_confidence_k")]
pub confidence_k: f64,
#[serde(default = "default_prior_base")]
pub prior_base: f64,
#[serde(default = "default_prior_max")]
pub prior_max: f64,
}
fn default_confidence_k() -> f64 { 15.0 }
fn default_prior_base() -> f64 { 50.0 }
fn default_prior_max() -> f64 { 80.0 }
impl Default for CalculatorConfig {
fn default() -> Self {
Self {
confidence_k: default_confidence_k(),
prior_base: default_prior_base(),
prior_max: default_prior_max(),
}
}
}
impl CalculatorConfig {
pub fn from_file(path: &Path) -> Result<Self> {
let content = std::fs::read_to_string(path)
.map_err(|e| BuilderError::InvalidConfig(format!("Failed to read config file: {}", e)))?;
serde_json::from_str(&content)
.map_err(|e| BuilderError::InvalidConfig(format!("Failed to parse config JSON: {}", e)).into())
}
pub fn to_file(&self, path: &Path) -> Result<()> {
let content = serde_json::to_string_pretty(self)
.map_err(|e| BuilderError::InvalidConfig(format!("Failed to serialize config: {}", e)))?;
std::fs::write(path, content)
.map_err(|e| BuilderError::InvalidConfig(format!("Failed to write config file: {}", e)).into())
}
}
pub mod presets {
use super::CalculatorConfig;
pub fn testing() -> CalculatorConfig {
CalculatorConfig {
confidence_k: 5.0,
prior_base: 50.0,
prior_max: 80.0,
}
}
pub fn conservative() -> CalculatorConfig {
CalculatorConfig {
confidence_k: 30.0,
prior_base: 60.0,
prior_max: 80.0,
}
}
pub fn aggressive() -> CalculatorConfig {
CalculatorConfig {
confidence_k: 10.0,
prior_base: 40.0,
prior_max: 90.0,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = CalculatorConfig::default();
assert_eq!(config.confidence_k, 15.0);
assert_eq!(config.prior_base, 50.0);
assert_eq!(config.prior_max, 80.0);
}
#[test]
fn test_presets() {
let testing = presets::testing();
assert_eq!(testing.confidence_k, 5.0);
let conservative = presets::conservative();
assert_eq!(conservative.confidence_k, 30.0);
let aggressive = presets::aggressive();
assert_eq!(aggressive.confidence_k, 10.0);
}
#[test]
fn test_config_serialization() {
let config = CalculatorConfig {
confidence_k: 25.0,
prior_base: 55.0,
prior_max: 85.0,
};
let json = serde_json::to_string(&config).unwrap();
let deserialized: CalculatorConfig = serde_json::from_str(&json).unwrap();
assert_eq!(config.confidence_k, deserialized.confidence_k);
assert_eq!(config.prior_base, deserialized.prior_base);
assert_eq!(config.prior_max, deserialized.prior_max);
}
#[test]
fn test_partial_config_deserialization() {
let json = r#"{"confidence_k": 25.0}"#;
let config: CalculatorConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.confidence_k, 25.0);
assert_eq!(config.prior_base, 50.0); assert_eq!(config.prior_max, 80.0); }
}