Crates.io | cache-any |
lib.rs | cache-any |
version | 1.1.3 |
source | src |
created_at | 2024-11-22 16:31:51.528551 |
updated_at | 2024-11-23 12:55:55.852015 |
description | A cache library for Rust |
homepage | |
repository | https://github.com/caojen/cache-any |
max_upload_size | |
id | 1457530 |
size | 86,157 |
A cache library for Rust.
This library provides a trait Cache
and some implementations of it. It defines the basic operations of a cache, for example, caches::Cache::get
, caches::Cache::set
. All functions are async, because we may use async storage backends. All caches are key-value based.
By default, it provides a simple memory cache as example. See caches::MemoryCache
.
redis
: Use redis as storage backend. See caches::RedisCache
.mysql
: Use mysql as storage backend. See caches::MySqlCache
.Add cache-any
to your Cargo.toml
:
[dependencies]
cache-any = { version = "1", features = ["full"] }
Cacheable
value.Cacheable
is a trait that describes how to convert a value
to bytes and vice versa.
A cache can store any value that implements Cacheable
. That is, you can store usize and string (or any other types) at the same time. But you need to know the exact type when you retrieve the value.
We use caches::MemoryCache
as example:
let cache = MemoryCache::default();
// The cache is empty, so get returns None.
assert!(cache.get::<()>("non-existent-key").await.unwrap().is_none());
// [SET a -> 1]
cache.set("a", 1).await.unwrap();
// [GET a] -> Some(1)
let a_value: u8 = cache.get("a").await.unwrap().unwrap();
assert_eq!(a_value, 1);
// you can do type casting, using u16 instead of u8 as an example.
let a_value: u16 = cache.get("a").await.unwrap().unwrap();
assert_eq!(a_value, 1);
// you can also store String in the same cache:
cache.set("b", String::from("hello")).await.unwrap();
let b_value: String = cache.get("b").await.unwrap().unwrap();
assert_eq!(b_value, String::from("hello"));
More examples: GitHub
You can extend Cacheable
for your own types. For example, you can define a struct and implement Cacheable
for it:
#[derive(serde::Serialize, serde::Deserialize)] // for json
struct MyStruct {
a: u8,
b: String,
}
In this case, we use serde_json
to convert the struct to bytes and vice versa:
impl Cacheable for MyStruct {
fn to_bytes(&self) -> Vec<u8> {
serde_json::to_vec(self).unwrap()
}
fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self> {
let ret = serde_json::from_slice(bytes)?;
Ok(ret)
}
}
Then you can store MyStruct
in the cache:
cache.set("my-struct", MyStruct { a: 1, b: String::from("hello") }).await.unwrap();
Any contributions are welcome.
If you find any useful cache implementation, feel free to open an issue or a pull request at Github.
If bugs are found, just file an issue at Github, and I will fix it ASAP.
This project is licensed under the MIT License.