Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Crate kash

Source
Expand description

crates.io version build status downloads docs.rs docs MIT licensed dependency status

Caching structures and simplified function memoization, using #[kash] macro.

use kash::kash;

/// Defines a function named `fib` that uses a cache implicitly named `FIB`.
/// By default, the cache will be the function's name in all caps.
#[kash]
fn fib(n: u64) -> u64 {
    if n == 0 || n == 1 { return n }
    fib(n-1) + fib(n-2)
}

Or if you want to limit the size and time-to-live:

use kash::kash;

const TTL: u64 = 1000;
#[kash(size = "100", ttl = "TTL")]
fn fib(n: u64) -> u64 {
    if n == 0 || n == 1 { return n }
    fib(n-1) + fib(n-2)
}

§Features

  • default: Includes ahash feature.
  • ahash: Enable ahash hasher as default hashing algorithm.
  • async: Include support for async functions.
  • redis_store: Include Redis cache store.
  • redis_async_std: Include async Redis support using async-std and async-std tls support, implies redis_store and async.
  • redis_tokio: Include async Redis support using tokio and tokio tls support, implies redis_store and async.
  • redis_connection_manager: Enable the optional connection-manager feature of redis. Any async redis caches created will use a connection manager instead of a MultiplexedConnection.
  • redis_ahash: Enable the optional ahash feature of redis.
  • disk_store: Include disk cache store.

use std::thread::sleep;
use std::time::Duration;
use kash::kash;

/// Use an explicit cache-type with a custom creation block and custom cache-key generating block
#[kash(
    size = "100",
    key(ty = "String", expr = r#"{ format!("{}{}", a, b) }"#)
)]
fn keyed(a: &str, b: &str) -> usize {
    let size = a.len() + b.len();
    sleep(Duration::new(size as u64, 0));
    size
}

use kash::{kash, RedisCacheError};
use kash::AsyncRedisCache;
use thiserror::Error;

#[derive(Error, Debug, PartialEq, Clone)]
enum ExampleError {
    #[error("error with redis cache `{0}`")]
    RedisError(String),
}

impl From<RedisCacheError> for ExampleError {
    fn from(e: RedisCacheError) -> Self {
        ExampleError::RedisError(format!("{:?}", e))
    }
}

/// Cache the results of an async function in redis. Cache
/// keys will be prefixed with `cache_redis_prefix`.
#[kash(redis)]
async fn async_kash_sleep_secs(secs: u64) -> Result<String, ExampleError> {
    std::thread::sleep(std::time::Duration::from_secs(secs));
    Ok(secs.to_string())
}

use kash::{kash, DiskCacheError};
use kash::DiskCache;
use thiserror::Error;

#[derive(Error, Debug, PartialEq, Clone)]
enum ExampleError {
    #[error("error with disk cache `{0}`")]
    DiskError(String),
}

impl From<DiskCacheError> for ExampleError {
    fn from(e: DiskCacheError) -> Self {
        ExampleError::DiskError(format!("{:?}", e))
    }
}

/// Cache the results of a function on disk.
/// Cache files will be stored under the system cache dir
/// unless otherwise specified with `dir` or the `create` argument.
#[kash(disk)]
fn kash_sleep_secs(secs: u64) -> Result<String, ExampleError> {
    std::thread::sleep(std::time::Duration::from_secs(secs));
    Ok(secs.to_string())
}

Functions defined via macros will have their result, cached using the function’s arguments as a key by default.

When a macro-defined function is called, the function’s cache is first checked for an already computed (and still valid) value before evaluating the function body.

See examples directory for more examples.

Re-exports§

pub use stores::AsyncRedisCache;redis_async_std or redis_tokio
pub use stores::DiskCache;disk_store
pub use stores::DiskCacheError;disk_store
pub use stores::RedisCache;redis_store
pub use stores::RedisCacheError;redis_store

Modules§

stores

Traits§

IOKash
Cache operations on an io-connected store
IOKashAsyncasync

Attribute Macros§

kash
Define a memoized function