use super::error::{ProfileError, ProfileResult};
use super::provider_registry::ProviderSource;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::Path;
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct ProfileLockfile {
pub version: String,
pub profiles: HashMap<String, ProfileLockEntry>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ProfileLockEntry {
pub name: String,
pub version: String,
pub installed_at: String,
pub files: Vec<String>,
#[serde(default)]
pub integrity: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub commit: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub provider_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source: Option<ProviderSource>,
}
impl ProfileLockfile {
pub fn new() -> Self {
Self {
version: "1.0.0".to_string(),
profiles: HashMap::new(),
}
}
pub fn load(path: &Path) -> ProfileResult<Self> {
if !path.exists() {
return Ok(Self::new());
}
let content = std::fs::read_to_string(path)?;
let lockfile: Self =
serde_json::from_str(&content).map_err(|_| ProfileError::InvalidManifest {
reason: "Lockfile is corrupted".to_string(),
})?;
Ok(lockfile)
}
pub fn save(&self, path: &Path) -> ProfileResult<()> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let json = serde_json::to_string_pretty(self)?;
std::fs::write(path, json)?;
Ok(())
}
pub fn is_installed(&self, name: &str) -> bool {
self.profiles.contains_key(name)
}
pub fn get_profile(&self, name: &str) -> Option<&ProfileLockEntry> {
self.profiles.get(name)
}
pub fn add_profile(&mut self, entry: ProfileLockEntry) {
self.profiles.insert(entry.name.clone(), entry);
}
pub fn remove_profile(&mut self, name: &str) -> Option<ProfileLockEntry> {
self.profiles.remove(name)
}
pub fn find_file_owner(&self, file_path: &str) -> Option<&str> {
for (name, entry) in &self.profiles {
if entry.files.contains(&file_path.to_string()) {
return Some(name);
}
}
None
}
}