use std::collections::HashMap; use std::sync::{Arc, Mutex}; use crate::error::{DocTreeError, Result}; /// Storage backend for doctree pub struct RedisStorage { // Using a simple in-memory storage for demonstration // In a real implementation, this would be a Redis client collections: Arc>>>, } impl RedisStorage { /// Create a new RedisStorage instance /// /// # Arguments /// /// * `url` - Redis connection URL (e.g., "redis://localhost:6379") /// This is ignored in the in-memory implementation /// /// # Returns /// /// A new RedisStorage instance or an error pub fn new(_url: &str) -> Result { Ok(Self { collections: Arc::new(Mutex::new(HashMap::new())), }) } /// Store a collection entry /// /// # Arguments /// /// * `collection` - Collection name /// * `key` - Entry key /// * `value` - Entry value /// /// # Returns /// /// Ok(()) on success or an error pub fn store_collection_entry(&self, collection: &str, key: &str, value: &str) -> Result<()> { let mut collections = self.collections.lock().unwrap(); // Get or create the collection let collection_entries = collections .entry(format!("collections:{}", collection)) .or_insert_with(HashMap::new); // Store the entry collection_entries.insert(key.to_string(), value.to_string()); Ok(()) } /// Get a collection entry /// /// # Arguments /// /// * `collection` - Collection name /// * `key` - Entry key /// /// # Returns /// /// The entry value or an error pub fn get_collection_entry(&self, collection: &str, key: &str) -> Result { let collections = self.collections.lock().unwrap(); // Get the collection let collection_key = format!("collections:{}", collection); let collection_entries = collections.get(&collection_key) .ok_or_else(|| DocTreeError::CollectionNotFound(collection.to_string()))?; // Get the entry collection_entries.get(key) .cloned() .ok_or_else(|| DocTreeError::FileNotFound(key.to_string())) } /// Delete a collection entry /// /// # Arguments /// /// * `collection` - Collection name /// * `key` - Entry key /// /// # Returns /// /// Ok(()) on success or an error pub fn delete_collection_entry(&self, collection: &str, key: &str) -> Result<()> { let mut collections = self.collections.lock().unwrap(); // Get the collection let collection_key = format!("collections:{}", collection); let collection_entries = collections.get_mut(&collection_key) .ok_or_else(|| DocTreeError::CollectionNotFound(collection.to_string()))?; // Remove the entry collection_entries.remove(key); Ok(()) } /// List all entries in a collection /// /// # Arguments /// /// * `collection` - Collection name /// /// # Returns /// /// A vector of entry keys or an error pub fn list_collection_entries(&self, collection: &str) -> Result> { let collections = self.collections.lock().unwrap(); // Get the collection let collection_key = format!("collections:{}", collection); let collection_entries = collections.get(&collection_key) .ok_or_else(|| DocTreeError::CollectionNotFound(collection.to_string()))?; // Get the keys let keys = collection_entries.keys().cloned().collect(); Ok(keys) } /// Delete a collection /// /// # Arguments /// /// * `collection` - Collection name /// /// # Returns /// /// Ok(()) on success or an error pub fn delete_collection(&self, collection: &str) -> Result<()> { let mut collections = self.collections.lock().unwrap(); // Remove the collection collections.remove(&format!("collections:{}", collection)); Ok(()) } /// Check if a collection exists /// /// # Arguments /// /// * `collection` - Collection name /// /// # Returns /// /// true if the collection exists, false otherwise pub fn collection_exists(&self, collection: &str) -> Result { let collections = self.collections.lock().unwrap(); // Check if the collection exists let exists = collections.contains_key(&format!("collections:{}", collection)); Ok(exists) } } // Implement Clone for RedisStorage impl Clone for RedisStorage { fn clone(&self) -> Self { Self { collections: Arc::clone(&self.collections), } } }