use chrono::{DateTime, Utc};
use color_eyre::Result;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VmMetadata {
pub name: String,
pub os: Option<String>,
pub template: Option<String>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct StateFile {
pub vms: HashMap<String, VmMetadata>,
}
pub fn load(path: &Path) -> Result<StateFile> {
if !path.exists() {
return Ok(StateFile::default());
}
let content = fs::read_to_string(path)?;
if content.trim().is_empty() {
return Ok(StateFile::default());
}
let parsed: StateFile = serde_json::from_str(&content)?;
Ok(parsed)
}
pub fn save(path: &Path, state: &StateFile) -> Result<()> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
let content = serde_json::to_string_pretty(state)?;
fs::write(path, content)?;
Ok(())
}
pub fn upsert_vm(path: &Path, metadata: VmMetadata) -> Result<()> {
let mut state = load(path)?;
state.vms.insert(metadata.name.clone(), metadata);
save(path, &state)
}
pub fn remove_vm(path: &Path, name: &str) -> Result<()> {
let mut state = load(path)?;
state.vms.remove(name);
save(path, &state)
}
pub fn remove_vm_from_state(state: &mut StateFile, name: &str) {
state.vms.remove(name);
}