diff --git a/README.md b/README.md new file mode 100644 index 0000000..84ee6d4 --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +# objcache + +Cache serde-able objects with Redis. + +## Quick overview + +Imagine you have the following: + +1) A struct or enum that implements `Serialize` and `Deserialize` + +```rust +#[derive(Serialize, Deserialize)] +struct Item { + value: usize, +} +``` + +2) An expensive function that creates an instance of that struct or enum + +```rust +async fn get_item(v: usize) -> Result { + // your business logic here + Ok(Item { value: v }) +} +``` + +3) A redis connection + +```rust +let client = RedisClient::new((IpAddr::V4(Ipv4Addr::LOCALHOST), 6379)).unwrap(); +``` + +This library lets you add a cache to your application by `wrap()`ing your function: + +```rust +let item = client.wrap( + get_item, + &RedisCacheArgs { + lock_name: b"item_lock", + key_name: b"item", + expiry: Duration::from_secs(5), + }, +)(100) +.await?; + +assert_eq!(item.value, 100); +``` + +That's it! Any call to the wrapped function will reuse the latest response if it is not +older than 5 seconds. + +## Not implemented + +* Cache depending on the input parameters +* Non-async wrap functions (should be easy to implement with some refactoring) + +## Status + +More of a proof of concept, there may be some big hidden issues. + +## Available methods + +|Method|Use case| +|---|---| +|`wrap()`|You want to unconditionally cache a response| +|`wrap_opt()`|Your function returns an `Option` and you only want to cache `Some` responses| +|`wrap_const()`|You want to select whether or not to cache depending on a separate parameter taking `CacheDecision`| +|`wrap_on()`|You have a function that takes your `Item` and returns a `CacheDecision`|