cache_any/lib.rs
1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2#![cfg_attr(feature = "redis", allow(dependency_on_unit_never_type_fallback))]
3#![forbid(unsafe_code)]
4
5//! A cache library for Rust.
6//!
7//! This library provides a trait [`Cache`] and some
8//! implementations of it.
9//!
10//! It defines the basic operations of a cache, for
11//! example, [`caches::Cache::get`], [`caches::Cache::set`].
12//! All functions are async, because we may use async storage backends.
13//!
14//! All caches are key-value based.
15//!
16//! By default, it provides a simple memory cache as example. See [`caches::MemoryCache`].
17//! But it's not recommended to use [`caches::MemoryCache`] directly in production.
18//!
19//! Other caches are available in below features:
20//!
21//! * `redis`: Use redis as storage backend. See [`caches::RedisCache`].
22//! * `mysql`: Use mysql as storage backend. See [`caches::MySqlCache`].
23//!
24//! ## Usage
25//!
26//! Add `cache-any` to your `Cargo.toml`:
27//!
28//! ```toml
29//! [dependencies]
30//! cache-any = { version = "1", features = ["full"] }
31//! ```
32//!
33//! ## Concepts
34//!
35//! * **Key**: Specified by the cache implementation. Usually it is a string-like type (&str, String, ...).
36//! * **Value**: The value of a cache is a [`Cacheable`] value.
37//!
38//! [`Cacheable`] is a trait that describes how to convert a `value` to bytes and vice versa.
39//!
40//! A cache can store any value that implements [`Cacheable`].
41//! That is, you can store usize and string (or any other types) at the same time.
42//! But you need to know the exact type when you retrieve the value.
43//!
44//! ## Basic Usage
45//!
46//! We use [`caches::MemoryCache`] as example.
47//!
48//! ```rust
49//! let cache = MemoryCache::default();
50//!
51//! // The cache is empty, so `get` returns None.
52//! assert!(cache.get::<()>("non-existent-key").await.unwrap().is_none());
53//!
54//! // [SET a -> 1]
55//! cache.set("a", 1).await.unwrap();
56//!
57//! // [GET a] -> Some(1)
58//! let a_value: u8 = cache.get("a").await.unwrap().unwrap();
59//! assert_eq!(a_value, 1);
60//!
61//! // you can do type casting, using u16 instead of u8 as an example.
62//! let a_value: u16 = cache.get("a").await.unwrap().unwrap();
63//! assert_eq!(a_value, 1);
64//!
65//! // you can also store [`String`] in the same cache:
66//! cache.set("b", String::from("hello")).await.unwrap();
67//! let b_value: String = cache.get("b").await.unwrap().unwrap();
68//! assert_eq!(b_value, String::from("hello"));
69//! ```
70//!
71//! ## Extend Cacheable
72//!
73//! You can extend [`Cacheable`] for your own types.
74//! For example, you can define a struct and implement [`Cacheable`] for it.
75//!
76//! ```rust
77//! #[derive(serde::Serialize, serde::Deserialize)] // for json
78//! struct MyStruct {
79//! a: u8,
80//! b: String,
81//! }
82//! ```
83//!
84//! In this case, we use `serde_json` to convert the struct to bytes and vice versa.
85//!
86//! ```rust,ignore
87//! impl Cacheable for MyStruct {
88//! fn to_bytes(&self) -> Vec<u8> {
89//! serde_json::to_vec(self).unwrap()
90//! }
91//!
92//! fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self> {
93//! let ret = serde_json::from_slice(bytes)?;
94//! Ok(ret)
95//! }
96//! }
97//! ```
98//!
99//! Then you can store `MyStruct` in the cache:
100//!
101//! ```rust
102//! cache.set("my-struct", MyStruct { a: 1, b: String::from("hello") }).await.unwrap();
103//! ```
104//!
105//! ## Work in Progress
106//!
107//! * Add examples for each cache implementation.
108//!
109//! ## Contributing
110//!
111//! Any contributions are welcome.
112//!
113//! If you find any useful cache implementation,
114//! feel free to open an issue or a pull request at [Github](https://github.com/caojen/cache-any).
115//!
116//! If bugs are found, just file an issue at [Github](https://github.com/caojen/cache-any), and I will fix it **ASAP**.
117//!
118//! ## License
119//!
120//! This project is licensed under the MIT License.
121
122mod cacheable;
123pub use cacheable::*;
124
125mod caches;
126pub use caches::*;
127
128#[test]
129fn it_works() {
130 println!("it works")
131}