use super::error::{CatalogError, CatalogResult};
use super::providers;
use super::traits::CatalogProvider;
use crate::storage::StorageManager;
use std::collections::HashMap;
use std::sync::Arc;
pub struct CatalogRegistry {
catalogs: HashMap<String, Box<dyn CatalogProvider>>,
storage: Arc<StorageManager>,
}
impl CatalogRegistry {
pub fn new(storage: Arc<StorageManager>) -> Self {
let mut registry = Self {
catalogs: HashMap::new(),
storage,
};
providers::register_all_catalogs(&mut registry);
registry
}
pub fn register(&mut self, name: &str, mut catalog: Box<dyn CatalogProvider>) {
if let Err(e) = catalog.init(self.storage.clone()) {
log::warn!("Failed to initialize catalog '{}': {}", name, e);
}
self.catalogs.insert(name.to_string(), catalog);
log::info!("Registered catalog provider: {}", name);
}
pub fn get(&self, name: &str) -> Option<&Box<dyn CatalogProvider>> {
self.catalogs.get(name)
}
pub fn get_mut(&mut self, name: &str) -> Option<&mut Box<dyn CatalogProvider>> {
self.catalogs.get_mut(name)
}
pub fn list_catalog_names(&self) -> Vec<String> {
self.catalogs.keys().cloned().collect()
}
pub fn has_catalog(&self, name: &str) -> bool {
self.catalogs.contains_key(name)
}
pub fn catalog_count(&self) -> usize {
self.catalogs.len()
}
pub fn save_catalog(&self, catalog_name: &str) -> CatalogResult<()> {
let catalog = self
.catalogs
.get(catalog_name)
.ok_or_else(|| CatalogError::CatalogNotFound(catalog_name.to_string()))?;
let data = catalog.save().map_err(|e| {
CatalogError::OperationFailed(format!(
"Failed to save catalog '{}': {}",
catalog_name, e
))
})?;
self.storage
.save_catalog_provider(catalog_name, &data)
.map_err(|e| {
CatalogError::OperationFailed(format!(
"Failed to persist catalog '{}': {}",
catalog_name, e
))
})?;
log::debug!("Saved catalog '{}': {} bytes", catalog_name, data.len());
Ok(())
}
pub fn save_all(&self) -> CatalogResult<()> {
for (name, catalog) in &self.catalogs {
let data = catalog.save().map_err(|e| {
CatalogError::OperationFailed(format!("Failed to save catalog '{}': {}", name, e))
})?;
self.storage
.save_catalog_provider(name, &data)
.map_err(|e| {
CatalogError::OperationFailed(format!(
"Failed to persist catalog '{}': {}",
name, e
))
})?;
log::debug!("Saved catalog '{}': {} bytes", name, data.len());
}
Ok(())
}
pub fn load_all(&mut self) -> CatalogResult<()> {
for (name, catalog) in &mut self.catalogs {
log::debug!("Loading catalog '{}'", name);
if let Some(data) = self.storage.load_catalog_provider(name).map_err(|e| {
CatalogError::OperationFailed(format!("Failed to load catalog '{}': {}", name, e))
})? {
catalog.load(&data).map_err(|e| {
CatalogError::OperationFailed(format!(
"Failed to deserialize catalog '{}': {}",
name, e
))
})?;
log::debug!("Loaded catalog '{}': {} bytes", name, data.len());
} else {
log::debug!(
"No stored data found for catalog '{}', using empty state",
name
);
}
}
Ok(())
}
#[allow(dead_code)] pub fn storage(&self) -> Arc<StorageManager> {
self.storage.clone()
}
}