Skip to content

Commit f44af35

Browse files
KuShpszymkowiak
andauthored
chore(init): accept trailing commas in JSON configs via serde_json_lenient (#89)
Only parse_json_config() uses lenient parsing. All other JSON handling stays on serde_json for type compatibility (axum, MCP, hooks). Co-authored-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu> Co-authored-by: KuSh <kush@users.noreply.github.com>
1 parent 0dd366d commit f44af35

File tree

4 files changed

+27
-3
lines changed

4 files changed

+27
-3
lines changed

Cargo.lock

Lines changed: 15 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ fastembed = "4"
2626
# Serialization
2727
serde = { version = "1", features = ["derive"] }
2828
serde_json = { version = "1", features = ["preserve_order"] }
29+
serde_json_lenient = { version = "0.2", features = ["preserve_order"] }
2930
toml = "0.8"
3031

3132
# Error handling

crates/icm-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ tower-http = { workspace = true, optional = true }
4343
rust-embed = { workspace = true, optional = true }
4444
mime_guess = { workspace = true, optional = true }
4545
getrandom = { workspace = true, optional = true }
46+
serde_json_lenient = { workspace = true }
4647

4748
[dev-dependencies]
4849
tempfile = "3"

crates/icm-cli/src/main.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2604,12 +2604,20 @@ fn strip_jsonc_comments(content: &str) -> String {
26042604
}
26052605

26062606
/// Parse a JSON/JSONC config file, handling comments and empty files gracefully.
2607+
/// Parse a JSON config file with lenient parsing: accepts trailing commas
2608+
/// and JSONC comments (// and /* */). This is the only place we use lenient
2609+
/// parsing — all other JSON handling uses strict serde_json.
26072610
fn parse_json_config(config_path: &std::path::Path) -> Result<Value> {
26082611
let content = std::fs::read_to_string(config_path)
26092612
.with_context(|| format!("cannot read {}", config_path.display()))?;
26102613
let clean = strip_jsonc_comments(&content);
2611-
serde_json::from_str(&clean)
2612-
.with_context(|| format!("invalid JSON in {}", config_path.display()))
2614+
// Use serde_json_lenient to accept trailing commas in user-edited configs,
2615+
// then round-trip to serde_json::Value for compatibility with the rest of the codebase.
2616+
let lenient: serde_json_lenient::Value = serde_json_lenient::from_str(&clean)
2617+
.with_context(|| format!("invalid JSON in {}", config_path.display()))?;
2618+
let strict: Value = serde_json::from_str(&lenient.to_string())
2619+
.with_context(|| format!("JSON conversion error in {}", config_path.display()))?;
2620+
Ok(strict)
26132621
}
26142622

26152623
/// Inject ICM MCP server into a JSON config file. Returns a status string.

0 commit comments

Comments
 (0)