tiny-counter 0.1.0

Track event counts across time windows with fixed memory and fast queries
Documentation
use std::collections::HashMap;

use crate::{Result, Storage};

/// In-memory storage backend.
///
/// Stores data in a HashMap without any persistence. Useful for testing
/// and scenarios where persistence is not required.
pub struct MemoryStorage {
    data: HashMap<String, Vec<u8>>,
}

impl MemoryStorage {
    /// Creates a new empty MemoryStorage.
    pub fn new() -> Self {
        Self {
            data: HashMap::new(),
        }
    }
}

impl Default for MemoryStorage {
    fn default() -> Self {
        Self::new()
    }
}

impl Storage for MemoryStorage {
    fn save(&mut self, key: &str, data: Vec<u8>) -> Result<()> {
        self.data.insert(key.to_string(), data);
        Ok(())
    }

    fn load(&self, key: &str) -> Result<Option<Vec<u8>>> {
        Ok(self.data.get(key).cloned())
    }

    fn delete(&mut self, key: &str) -> Result<()> {
        self.data.remove(key);
        Ok(())
    }

    fn list_keys(&self) -> Result<Vec<String>> {
        Ok(self.data.keys().cloned().collect())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_save_then_load_returns_same_data() {
        let mut storage = MemoryStorage::new();
        let data = vec![1, 2, 3, 4, 5];

        storage.save("test_key", data.clone()).unwrap();
        let loaded = storage.load("test_key").unwrap();

        assert_eq!(loaded, Some(data));
    }

    #[test]
    fn test_load_nonexistent_key_returns_none() {
        let storage = MemoryStorage::new();
        let loaded = storage.load("nonexistent").unwrap();
        assert_eq!(loaded, None);
    }

    #[test]
    fn test_delete_removes_data() {
        let mut storage = MemoryStorage::new();
        let data = vec![1, 2, 3];

        storage.save("test_key", data).unwrap();
        storage.delete("test_key").unwrap();

        let loaded = storage.load("test_key").unwrap();
        assert_eq!(loaded, None);
    }

    #[test]
    fn test_save_overwrites_existing_key() {
        let mut storage = MemoryStorage::new();
        let data1 = vec![1, 2, 3];
        let data2 = vec![4, 5, 6];

        storage.save("test_key", data1).unwrap();
        storage.save("test_key", data2.clone()).unwrap();

        let loaded = storage.load("test_key").unwrap();
        assert_eq!(loaded, Some(data2));
    }

    #[test]
    fn test_default_trait() {
        let storage = MemoryStorage::default();
        let loaded = storage.load("any_key").unwrap();
        assert_eq!(loaded, None);
    }
}