From 204a4808069e0fc08c94ac7d297390982c2db379 Mon Sep 17 00:00:00 2001 From: Louis Knight-Webb Date: Thu, 19 Jun 2025 21:34:45 -0400 Subject: [PATCH 1/2] Task attempt 9211fe88-4979-4638-a6db-9d94cdcfcdfd - Final changes --- backend/src/bin/test_config.rs | 23 +++++++++++++++++ backend/src/models/config.rs | 46 ++++++++++++++++++++++++++++++++-- test_config.json | 8 ++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 backend/src/bin/test_config.rs create mode 100644 test_config.json diff --git a/backend/src/bin/test_config.rs b/backend/src/bin/test_config.rs new file mode 100644 index 00000000..2d30b88c --- /dev/null +++ b/backend/src/bin/test_config.rs @@ -0,0 +1,23 @@ +use vibe_kanban::models::config::Config; +use std::path::PathBuf; + +fn main() -> anyhow::Result<()> { + // Test loading config with missing keys + let test_path = PathBuf::from("../test_config.json"); + + println!("Testing config loading with missing keys..."); + println!("Original config content:"); + let content = std::fs::read_to_string(&test_path)?; + println!("{}", content); + + let config = Config::load(&test_path)?; + + println!("\nLoaded config (with defaults merged):"); + println!("{:#?}", config); + + println!("\nUpdated config file content:"); + let updated_content = std::fs::read_to_string(&test_path)?; + println!("{}", updated_content); + + Ok(()) +} diff --git a/backend/src/models/config.rs b/backend/src/models/config.rs index f1a9b147..7c48c2da 100644 --- a/backend/src/models/config.rs +++ b/backend/src/models/config.rs @@ -36,8 +36,16 @@ impl Config { pub fn load(config_path: &PathBuf) -> anyhow::Result { 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::(&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 { + // 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)?; diff --git a/test_config.json b/test_config.json new file mode 100644 index 00000000..258117de --- /dev/null +++ b/test_config.json @@ -0,0 +1,8 @@ +{ + "theme": "dark", + "executor": { + "type": "claude" + }, + "disclaimer_acknowledged": true, + "sound_alerts": true +} \ No newline at end of file From 55c8319078a5fc27f14706679cc68f5ae1bbfc4c Mon Sep 17 00:00:00 2001 From: Louis Knight-Webb Date: Thu, 19 Jun 2025 21:40:19 -0400 Subject: [PATCH 2/2] remove unnecessary --- backend/src/bin/test_config.rs | 23 ----------------------- test_config.json | 8 -------- 2 files changed, 31 deletions(-) delete mode 100644 backend/src/bin/test_config.rs delete mode 100644 test_config.json diff --git a/backend/src/bin/test_config.rs b/backend/src/bin/test_config.rs deleted file mode 100644 index 2d30b88c..00000000 --- a/backend/src/bin/test_config.rs +++ /dev/null @@ -1,23 +0,0 @@ -use vibe_kanban::models::config::Config; -use std::path::PathBuf; - -fn main() -> anyhow::Result<()> { - // Test loading config with missing keys - let test_path = PathBuf::from("../test_config.json"); - - println!("Testing config loading with missing keys..."); - println!("Original config content:"); - let content = std::fs::read_to_string(&test_path)?; - println!("{}", content); - - let config = Config::load(&test_path)?; - - println!("\nLoaded config (with defaults merged):"); - println!("{:#?}", config); - - println!("\nUpdated config file content:"); - let updated_content = std::fs::read_to_string(&test_path)?; - println!("{}", updated_content); - - Ok(()) -} diff --git a/test_config.json b/test_config.json deleted file mode 100644 index 258117de..00000000 --- a/test_config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "theme": "dark", - "executor": { - "type": "claude" - }, - "disclaimer_acknowledged": true, - "sound_alerts": true -} \ No newline at end of file