doctree_rust/doctree/src/storage.rs
2025-04-09 07:11:38 +02:00

169 lines
4.9 KiB
Rust

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<Mutex<HashMap<String, HashMap<String, String>>>>,
}
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<Self> {
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<String> {
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<Vec<String>> {
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<bool> {
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),
}
}
}