cache-any 1.1.2

A cache library for Rust
Documentation
# cache-any

[![Crates.io](https://img.shields.io/crates/v/cache-any)](https://crates.io/crates/cache-any)
[![Documentation](https://docs.rs/cache-any/badge.svg)](https://docs.rs/cache-any)
[![License](https://img.shields.io/crates/l/cache-any)](LICENSE)
[![Rust](https://img.shields.io/badge/rust-1.69%2B-blue.svg?maxAge=3600)](https://github.com/caojen/cache-any)
[![Downloads](https://img.shields.io/crates/d/cache-any)](https://crates.io/crates/cache-any)

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`.

## Features

* `redis`: Use redis as storage backend. See `caches::RedisCache`.
* `mysql`: Use mysql as storage backend. See `caches::MySqlCache`.

## Usage
Add `cache-any` to your `Cargo.toml`:

```toml
[dependencies]
cache-any = { version = "1", features = ["full"] }
```

## Concepts

* **Key**: Specified by the cache implementation. Usually it is a string-like type (&str, String, ...).
* **Value**: The value of a cache is a `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.

## Basic Usage

We use `caches::MemoryCache` as example:

```rust
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"));
```


## Extend Cacheable

You can extend `Cacheable` for your own types. For example, you can define a struct and implement `Cacheable` for it:

```rust
#[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:


```rust
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:

```rust
cache.set("my-struct", MyStruct { a: 1, b: String::from("hello") }).await.unwrap();
```


## Work in Progress

* Add examples for each cache implementation.

## Contributing

Any contributions are welcome.

If you find any useful cache implementation, feel free to open an issue or a pull request at [Github](https://github.com/caojen/cache-any).

If bugs are found, just file an issue at [Github](https://github.com/caojen/cache-any), and I will fix it **ASAP**.

## License

This project is licensed under the MIT License.