use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use wipe_core::Store;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ProjectEntry {
pub path: String,
#[serde(default)]
pub name: String,
}
#[derive(Debug, Default, Serialize, Deserialize)]
struct RegistryFile {
#[serde(default)]
projects: Vec<String>,
}
fn registry_path() -> Option<PathBuf> {
directories::ProjectDirs::from("dev", "wipe", "wipe")
.map(|d| d.config_dir().join("projects.json"))
}
fn load() -> RegistryFile {
registry_path()
.and_then(|p| std::fs::read(p).ok())
.and_then(|b| serde_json::from_slice(&b).ok())
.unwrap_or_default()
}
fn save(reg: &RegistryFile) {
if let Some(path) = registry_path() {
if let Some(dir) = path.parent() {
let _ = std::fs::create_dir_all(dir);
}
if let Ok(mut s) = serde_json::to_string_pretty(reg) {
s.push('\n');
let _ = std::fs::write(path, s);
}
}
}
pub fn register(root: &Path) {
let canonical = std::fs::canonicalize(root).unwrap_or_else(|_| root.to_path_buf());
let key = canonical.display().to_string();
let mut reg = load();
if !reg.projects.iter().any(|p| p == &key) {
reg.projects.push(key);
reg.projects.sort();
save(®);
}
}
pub fn list() -> Vec<ProjectEntry> {
load()
.projects
.into_iter()
.filter_map(|path| {
let store = Store::open(&path).ok()?;
let name = store.load_board().map(|b| b.name).unwrap_or_default();
Some(ProjectEntry { path, name })
})
.collect()
}