Merge task attempt 9211fe88-4979-4638-a6db-9d94cdcfcdfd into main

This commit is contained in:
Louis Knight-Webb
2025-06-19 21:40:28 -04:00

View File

@@ -36,8 +36,16 @@ impl Config {
pub fn load(config_path: &PathBuf) -> anyhow::Result<Self> {
if config_path.exists() {
let content = std::fs::read_to_string(config_path)?;
let config: Config = serde_json::from_str(&content)?;
Ok(config)
// Try to deserialize as is first
match serde_json::from_str::<Config>(&content) {
Ok(config) => Ok(config),
Err(_) => {
// If full deserialization fails, merge with defaults
let config = Self::load_with_defaults(&content, config_path)?;
Ok(config)
}
}
} else {
let config = Config::default();
config.save(config_path)?;
@@ -45,6 +53,40 @@ impl Config {
}
}
fn load_with_defaults(content: &str, config_path: &PathBuf) -> anyhow::Result<Self> {
// Parse as generic JSON value
let existing_value: serde_json::Value = serde_json::from_str(content)?;
// Get default config as JSON value
let default_config = Config::default();
let default_value = serde_json::to_value(&default_config)?;
// Merge existing config with defaults
let merged_value = Self::merge_json_values(default_value, existing_value);
// Deserialize merged value back to Config
let config: Config = serde_json::from_value(merged_value)?;
// Save the updated config with any missing defaults
config.save(config_path)?;
Ok(config)
}
fn merge_json_values(mut base: serde_json::Value, overlay: serde_json::Value) -> serde_json::Value {
match (&mut base, overlay) {
(serde_json::Value::Object(base_map), serde_json::Value::Object(overlay_map)) => {
for (key, value) in overlay_map {
base_map.entry(key).and_modify(|base_value| {
*base_value = Self::merge_json_values(base_value.clone(), value.clone());
}).or_insert(value);
}
base
}
(_, overlay) => overlay, // Use overlay value for non-objects
}
}
pub fn save(&self, config_path: &PathBuf) -> anyhow::Result<()> {
let content = serde_json::to_string_pretty(self)?;
std::fs::write(config_path, content)?;