use crate::services::configuration_service::{configuration, ConfigurationService, PmatConfig};
use anyhow::Result;
use std::path::PathBuf;
use tracing::info;
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub async fn handle_configuration(
show: bool,
edit: bool,
validate: bool,
reset: bool,
section: Option<String>,
set: Vec<String>,
config_path: Option<PathBuf>,
) -> Result<()> {
let config_service = create_config_service(config_path);
execute_configuration_command(
&config_service,
ConfigurationCommand {
show,
edit,
validate,
reset,
section,
set,
},
)
.await
}
struct ConfigurationCommand {
show: bool,
edit: bool,
validate: bool,
reset: bool,
section: Option<String>,
set: Vec<String>,
}
fn create_config_service(config_path: Option<PathBuf>) -> std::sync::Arc<ConfigurationService> {
if let Some(path) = config_path {
std::sync::Arc::new(ConfigurationService::new(Some(path)))
} else {
configuration()
}
}
async fn execute_configuration_command(
config_service: &ConfigurationService,
cmd: ConfigurationCommand,
) -> Result<()> {
if cmd.reset {
reset_configuration(config_service).await?;
println!("Configuration reset to defaults");
return Ok(());
}
if cmd.validate {
return validate_configuration(config_service).await;
}
if !cmd.set.is_empty() {
return set_configuration_values(config_service, cmd.set).await;
}
if cmd.edit {
return edit_configuration(config_service).await;
}
if cmd.show || cmd.section.is_some() {
show_configuration(config_service, cmd.section).await
} else {
show_configuration_overview(config_service).await
}
}
include!("configuration_handlers_display.rs");
include!("configuration_handlers_setters.rs");
include!("configuration_handlers_validation.rs");
include!("configuration_handlers_operations.rs");
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[tokio::test]
async fn test_configuration_overview() {
let temp_dir = tempdir().unwrap();
let config_path = temp_dir.path().join("test_config.toml");
let config_service = std::sync::Arc::new(ConfigurationService::new(Some(config_path)));
let result = show_configuration_overview(&config_service).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_configuration_validation() {
let temp_dir = tempdir().unwrap();
let config_path = temp_dir.path().join("test_config.toml");
let config_service = std::sync::Arc::new(ConfigurationService::new(Some(config_path)));
let result = validate_configuration(&config_service).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_set_configuration_values() {
let temp_dir = tempdir().unwrap();
let config_path = temp_dir.path().join("test_config.toml");
let config_service = std::sync::Arc::new(ConfigurationService::new(Some(config_path)));
let set_values = vec![
"quality.max_complexity=25".to_string(),
"system.verbose=true".to_string(),
];
let result = set_configuration_values(&config_service, set_values).await;
assert!(result.is_ok());
let config = config_service.get_config().unwrap();
assert_eq!(config.quality.max_complexity, 25);
assert!(config.system.verbose);
}
#[tokio::test]
async fn test_show_configuration_section() {
let config = crate::services::configuration_service::ConfigurationService::default_config();
let result = show_configuration_section(&config, "quality");
assert!(result.is_ok());
let result = show_configuration_section(&config, "invalid");
assert!(result.is_err());
}
#[tokio::test]
async fn test_reset_configuration() {
let temp_dir = tempdir().unwrap();
let config_path = temp_dir.path().join("test_config.toml");
let config_service = std::sync::Arc::new(ConfigurationService::new(Some(config_path)));
config_service
.update_config(|config| {
config.quality.max_complexity = 50;
Ok(())
})
.await
.unwrap();
let result = reset_configuration(&config_service).await;
assert!(result.is_ok());
let config = config_service.get_config().unwrap();
assert_eq!(config.quality.max_complexity, 30); }
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use proptest::prelude::*;
proptest! {
#[test]
fn basic_property_stability(_input in ".*") {
prop_assert!(true);
}
#[test]
fn module_consistency_check(_x in 0u32..1000) {
prop_assert!(_x < 1001);
}
}
}