Skip to content

Commit

Permalink
chore(docs): Add doc comments and update README.md (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike Rivnak authored May 18, 2024
1 parent f13d1d0 commit 6089d3e
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 8 deletions.
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,23 @@ use uuid::Uuid;

use pond_cache::Cache;

#[derive(Clone, serde::Serialize, serde::Deserialize)]
struct User {
pub first_name: String,
pub last_name: String,
}

fn main() {
let cache = Cache::new(PathBuf::from("./db.sqlite")).unwrap();

let key = Uuid::new_v4();
let value = String::from("Hello, world!");
let user_id = Uuid::new_v4();
let user = User {
first_name: "John",
last_name: "Doe",
};

cache.store(&key, value).unwrap();
cache.store(&user_id, user).unwrap();

let result: Option<String> = cache.get(&key).unwrap();
let result: Option<User> = cache.get(&key).unwrap();
}
```
138 changes: 134 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![crate_name = "pond_cache"]

use std::hash::{DefaultHasher, Hash, Hasher};
use std::path::PathBuf;

Expand All @@ -8,6 +10,7 @@ use serde::Serialize;

pub use rusqlite::Error;

/// Pond cache struct
pub struct Cache<T> {
path: PathBuf,
ttl: Duration,
Expand All @@ -25,10 +28,48 @@ where
}

impl<T: Serialize + DeserializeOwned + Clone> Cache<T> {
/// Create a new cache with a default time-to-live of 10 minutes
///
/// # Arguments
/// * `path` - Path to the SQLite database file
///
/// # Returns
/// A new cache instance
///
/// # Errors
/// Returns an error if the database connection cannot be established
///
/// # Example
/// ```rust
/// use pond_cache::Cache;
/// use std::path::PathBuf;
///
/// let cache: Cache<String> = Cache::new(PathBuf::from("cache.db")).expect("Failed to create cache");
/// ```
pub fn new(path: PathBuf) -> Result<Self, Error> {
Self::with_time_to_live(path, Duration::minutes(10))
}

/// Create a new cache with a custom time-to-live
///
/// # Arguments
/// * `path` - Path to the SQLite database file
/// * `ttl` - Time-to-live for cache entries
///
/// # Returns
/// A new cache instance
///
/// # Errors
/// Returns an error if the database connection cannot be established
///
/// # Example
/// ```rust
/// use pond_cache::Cache;
/// use std::path::PathBuf;
/// use chrono::Duration;
///
/// let cache: Cache<String> = Cache::with_time_to_live(PathBuf::from("cache.db"), Duration::minutes(5)).expect("Failed to create cache");
/// ```
pub fn with_time_to_live(path: PathBuf, ttl: Duration) -> Result<Self, Error> {
let db = Connection::open(path.as_path())?;

Expand All @@ -50,10 +91,28 @@ impl<T: Serialize + DeserializeOwned + Clone> Cache<T> {
})
}

pub fn get<K>(&self, key: K) -> Result<Option<T>, Error>
where
K: Hash,
{
/// Retrieve a value from the cache
///
/// # Arguments
/// * `key` - Key to retrieve the value for
///
/// # Returns
/// The value associated with the key, if it exists and has not expired
/// If the value does not exist or has expired, returns `None`
///
/// # Errors
/// Returns an error if the database connection cannot be established
///
/// # Example
/// ```rust
/// use pond_cache::Cache;
/// use std::path::PathBuf;
///
/// let cache: Cache<String> = Cache::new(PathBuf::from("cache.db")).expect("Failed to create cache");
/// let key = "key";
/// let value: Option<String> = cache.get(key).expect("Failed to get value");
/// ```
pub fn get<K: Hash>(&self, key: K) -> Result<Option<T>, Error> {
let db = Connection::open(self.path.as_path())?;

let mut stmt = db.prepare(
Expand Down Expand Up @@ -96,10 +155,63 @@ impl<T: Serialize + DeserializeOwned + Clone> Cache<T> {
}
}

/// Store a value in the cache
/// The value will be stored with the cache's time-to-live
/// If the value already exists, it will be replaced
///
/// # Arguments
/// * `key` - Key to store the value under
/// * `value` - Value to store
///
/// # Returns
/// Ok if the value was stored successfully
/// Err if the value could not be stored
///
/// # Errors
/// Returns an error if the database connection cannot be established
///
/// # Example
/// ```rust
/// use pond_cache::Cache;
/// use std::path::PathBuf;
///
/// let cache: Cache<String> = Cache::new(PathBuf::from("cache.db")).expect("Failed to create cache");
/// let key = "key";
/// let value = String::from("value");
/// cache.store(key, value).expect("Failed to store value");
/// ```
pub fn store<K: Hash>(&self, key: K, value: T) -> Result<(), Error> {
self.store_with_expiration(key, value, Utc::now() + self.ttl)
}

/// Store a value in the cache with a custom expiration time
/// If the value already exists, it will be replaced
///
/// # Arguments
/// * `key` - Key to store the value under
/// * `value` - Value to store
/// * `expiration` - Expiration time for the value
///
/// # Returns
/// Ok if the value was stored successfully
/// Err if the value could not be stored
///
/// # Errors
/// Returns an error if the database connection cannot be established
///
/// # Example
/// ```rust
/// use pond_cache::Cache;
/// use std::path::PathBuf;
/// use chrono::{Duration, Utc};
///
/// let cache: Cache<String> = Cache::new(PathBuf::from("cache.db")).expect("Failed to create cache");
/// let key = "key";
/// let value = String::from("value");
/// let expiration = Utc::now() + Duration::minutes(5);
///
/// cache.store_with_expiration(key, value, expiration).expect("Failed to store value");
/// ```
pub fn store_with_expiration<K: Hash>(
&self,
key: K,
Expand Down Expand Up @@ -134,6 +246,24 @@ impl<T: Serialize + DeserializeOwned + Clone> Cache<T> {
Ok(())
}

/// Clean up the cache by removing expired entries
/// This method should be called periodically to prevent the cache from growing indefinitely
///
/// # Returns
/// Ok if the cache was cleaned successfully
/// Err if the cache could not be cleaned
///
/// # Errors
/// Returns an error if the database connection cannot be established
///
/// # Example
/// ```rust
/// use pond_cache::Cache;
/// use std::path::PathBuf;
///
/// let cache: Cache<String> = Cache::new(PathBuf::from("cache.db")).expect("Failed to create cache");
/// cache.clean().expect("Failed to clean cache");
/// ```
pub fn clean(&self) -> Result<(), Error> {
let db = Connection::open(self.path.as_path())?;

Expand Down

0 comments on commit 6089d3e

Please sign in to comment.