use ryo_analysis::{UuidPersistence, UuidPersistenceError};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct FileUuidStorage {
file_path: PathBuf,
}
impl FileUuidStorage {
pub fn new(workspace_root: impl AsRef<Path>) -> Self {
let file_path = workspace_root
.as_ref()
.join(".ryo")
.join("uuid-mapping.json");
Self { file_path }
}
pub fn file_path(&self) -> &Path {
&self.file_path
}
}
impl UuidPersistence for FileUuidStorage {
fn load(&self) -> Option<HashMap<String, String>> {
let content = std::fs::read_to_string(&self.file_path).ok()?;
serde_json::from_str(&content).ok()
}
fn save(&self, mappings: &HashMap<String, String>) -> Result<(), UuidPersistenceError> {
if let Some(parent) = self.file_path.parent() {
std::fs::create_dir_all(parent)?;
}
let content = serde_json::to_string_pretty(mappings)?;
std::fs::write(&self.file_path, content)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::TempDir;
#[test]
fn test_file_uuid_storage_roundtrip() {
let temp_dir = TempDir::new().unwrap();
let storage = FileUuidStorage::new(temp_dir.path());
assert!(storage.load().is_none());
let mut mappings = HashMap::new();
mappings.insert("test_crate::Foo".to_string(), "uuid-1".to_string());
mappings.insert("test_crate::Bar".to_string(), "uuid-2".to_string());
storage.save(&mappings).unwrap();
let loaded = storage.load().unwrap();
assert_eq!(loaded.len(), 2);
assert_eq!(loaded.get("test_crate::Foo"), Some(&"uuid-1".to_string()));
assert_eq!(loaded.get("test_crate::Bar"), Some(&"uuid-2".to_string()));
}
#[test]
fn test_file_uuid_storage_creates_directory() {
let temp_dir = TempDir::new().unwrap();
let storage = FileUuidStorage::new(temp_dir.path());
assert!(!temp_dir.path().join(".ryo").exists());
let mappings = HashMap::new();
storage.save(&mappings).unwrap();
assert!(temp_dir.path().join(".ryo").exists());
assert!(storage.file_path().exists());
}
}