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}