use std::path::{Path, PathBuf};
use serde_json::Value;
use crate::output::CliError;
pub fn resolve_data_dir(flag: Option<&Path>) -> Result<PathBuf, CliError> {
if let Some(p) = flag {
if !p.exists() {
return Err(CliError::not_found(
format!("--data-dir path does not exist: {}", p.display()),
Some("run `liber init <slug> <path>` to scaffold a fresh data directory".into()),
));
}
return Ok(p.to_path_buf());
}
if let Ok(env) = std::env::var("LIBER_DATA_DIR") {
let p = PathBuf::from(env);
if !p.exists() {
return Err(CliError::not_found(
format!("LIBER_DATA_DIR path does not exist: {}", p.display()),
Some("unset LIBER_DATA_DIR or point it at an existing directory".into()),
));
}
return Ok(p);
}
let local = PathBuf::from(".liber");
if local.exists() {
return Ok(local);
}
let cwd = PathBuf::from(".");
if looks_like_data_dir(&cwd) {
return Ok(cwd);
}
if let Some(home) = home_dir() {
let p = home.join(".liber");
if p.exists() {
return Ok(p);
}
}
Err(CliError::not_found(
"no liber data directory found".into(),
Some(
"set --data-dir, LIBER_DATA_DIR, or create one with `liber init <slug> <path>`"
.into(),
),
))
}
fn home_dir() -> Option<PathBuf> {
std::env::var_os("HOME").map(PathBuf::from)
}
fn looks_like_data_dir(dir: &Path) -> bool {
let must = dir.join("people.json");
if !must.exists() {
return false;
}
["products.json", "customers.json", "chats.json"]
.iter()
.any(|n| dir.join(n).exists())
}
pub fn load(dir: &Path, name: &str) -> Result<Value, CliError> {
let path = dir.join(format!("{name}.json"));
let bytes = std::fs::read(&path).map_err(|e| {
CliError::not_found(
format!("data file missing: {} ({e})", path.display()),
Some(format!(
"create {name}.json in {} (see `liber init` for a template)",
dir.display()
)),
)
})?;
serde_json::from_slice(&bytes).map_err(|e| {
CliError::data(
format!("invalid JSON in {}: {e}", path.display()),
Some("fix the JSON syntax and re-run".into()),
)
})
}