mod annotations;
mod app;
mod backup;
mod help;
mod hjson_index;
mod save;
mod schema;
mod widgets;
use std::path::Path;
use anyhow::{Context, Result};
use std::path::PathBuf;
pub fn run(project: &Path) -> Result<()> {
app::run(project)
}
pub struct InPlacePatchOutcome {
pub config_path: PathBuf,
pub backup: PathBuf,
}
pub fn apply_in_place_edits(
project_root: &Path,
updates: &[(String, serde_json::Value)],
) -> Result<InPlacePatchOutcome> {
if updates.is_empty() {
anyhow::bail!("apply_in_place_edits: no updates supplied");
}
let config_path = project_root.join("inkhaven.hjson");
let source = std::fs::read_to_string(&config_path)
.with_context(|| format!("read {}", config_path.display()))?;
let backup = save::write_backup(project_root, &source)
.context("write pre-patch backup")?;
let index = hjson_index::parse(&source)
.map_err(|e| anyhow::anyhow!("parse HJSON: {e}"))?;
let edits: Vec<save::Edit> = updates
.iter()
.map(|(path, value)| {
let kind = if index.leaves.contains_key(path) {
save::EditKind::Splice
} else {
save::EditKind::Append
};
save::Edit {
path: path.clone(),
new_value: value.clone(),
kind,
}
})
.collect();
let new_source = save::apply_edits(&index, &edits)
.context("apply HJSON edits")?;
let written = save::write_atomic(&config_path, &new_source)
.context("write inkhaven.hjson")?;
Ok(InPlacePatchOutcome {
config_path: written,
backup,
})
}