quickleaf/
lib.rs

1//! # Quickleaf Cache
2//!
3//! Quickleaf Cache is a Rust library that provides a simple and efficient in-memory cache with support for filtering, ordering, limiting results, TTL (Time To Live), event notifications, and optional persistent storage. It is designed to be lightweight and easy to use.
4//!
5//! ## Features
6//!
7//! - Insert and remove key-value pairs
8//! - Retrieve values by key
9//! - Clear the cache
10//! - List cache entries with support for filtering, ordering, and limiting results
11//! - **TTL (Time To Live) support** with lazy cleanup
12//! - **Persistent storage** using SQLite (optional feature)
13//! - Custom error handling
14//! - Event notifications for cache operations
15//! - Support for generic values using [valu3](https:
16//!
17//! ## Installation
18//!
19//! Add the following to your `Cargo.toml`:
20//!
21//! ```toml
22//! [dependencies]
23//! quickleaf = "0.4"
24//!
25//! # For persistence support (optional)
26//! quickleaf = { version = "0.4", features = ["persist"] }
27//! ```
28//!
29//! ## Usage
30//!
31//! Here's a basic example of how to use Quickleaf Cache:
32//!
33//! ```rust
34//! use quickleaf::{Quickleaf, ListProps, Order, Filter, prelude::*};
35//! use quickleaf::valu3::value::Value;
36//!
37//! fn main() {
38//!     let mut cache = Quickleaf::new(2);
39//!     cache.insert("key1", 1);
40//!     cache.insert("key2", 2);
41//!     cache.insert("key3", 3);
42//!
43//!     assert_eq!(cache.get("key1"), None);
44//!     assert_eq!(cache.get("key2"), Some(&2.to_value()));
45//!     assert_eq!(cache.get("key3"), Some(&3.to_value()));
46//!
47//!     let list_props = ListProps::default()
48//!         .order(Order::Asc);
49//!
50//!     let result = cache.list(list_props).unwrap();
51//!     for (key, value) in result {
52//!         println!("{}: {}", key, value);
53//!     }
54//! }
55//! ```
56//!
57//! ### Using Filters
58//!
59//! You can use filters to narrow down the results when listing cache entries. Here are some examples:
60//!
61//! #### Filter by Start With
62//!
63//! ```rust
64//! use quickleaf::{Quickleaf, ListProps, Order, Filter};
65//!
66//!
67//! fn main() {
68//!     let mut cache = Quickleaf::new(10);
69//!     cache.insert("apple", 1);
70//!     cache.insert("banana", 2);
71//!     cache.insert("apricot", 3);
72//!
73//!     let list_props = ListProps::default()
74//!         .order(Order::Asc)
75//!         .filter(Filter::StartWith("ap".to_string()));
76//!
77//!     let result = cache.list(list_props).unwrap();
78//!     for (key, value) in result {
79//!         println!("{}: {}", key, value);
80//!     }
81//! }
82//! ```
83//!
84//! #### Filter by End With
85//!
86//! ```rust
87//! use quickleaf::{Quickleaf, ListProps, Order, Filter};
88//!
89//! fn main() {
90//!     let mut cache = Quickleaf::new(10);
91//!     cache.insert("apple", 1);
92//!     cache.insert("banana", 2);
93//!     cache.insert("pineapple", 3);
94//!
95//!     let list_props = ListProps::default()
96//!         .order(Order::Asc)
97//!         .filter(Filter::EndWith("apple".to_string()));
98//!
99//!     let result = cache.list(list_props).unwrap();
100//!     for (key, value) in result {
101//!         println!("{}: {}", key, value);
102//!     }
103//! }
104//! ```
105//!
106//! #### Filter by Start And End With
107//!
108//! ```rust
109//! use quickleaf::{Quickleaf, ListProps, Order, Filter};
110//!
111//! fn main() {
112//!     let mut cache = Quickleaf::new(10);
113//!     cache.insert("applemorepie", 1);
114//!     cache.insert("banana", 2);
115//!     cache.insert("pineapplepie", 3);
116//!
117//!     let list_props = ListProps::default()
118//!         .order(Order::Asc)
119//!         .filter(Filter::StartAndEndWith("apple".to_string(), "pie".to_string()));
120//!
121//!     let result = cache.list(list_props).unwrap();
122//!     for (key, value) in result {
123//!         println!("{}: {}", key, value);
124//!     }
125//! }
126//! ```
127//!
128//! ### Using TTL (Time To Live)
129//!
130//! You can set TTL for cache entries to automatically expire them after a certain duration:
131//!
132//! ```rust
133//! use quickleaf::{Quickleaf, Duration};
134//!
135//! fn main() {
136//!     let mut cache = Quickleaf::new(10);
137//!     
138//!     
139//!     cache.insert_with_ttl("session", "user_data", Duration::from_secs(5));
140//!     
141//!     
142//!     let mut cache_with_default = Quickleaf::with_default_ttl(10, Duration::from_secs(60));
143//!     cache_with_default.insert("key", "value");
144//!     
145//!     
146//!     let removed_count = cache.cleanup_expired();
147//!     println!("Removed {} expired items", removed_count);
148//! }
149//! ```
150//!
151//! ### Using Events
152//!
153//! You can use events to get notified when cache entries are inserted, removed, or cleared. Here is an example:
154//!
155//! ```rust
156//! use quickleaf::{Quickleaf, Event, prelude::*};
157//! use std::sync::mpsc::channel;
158//! use quickleaf::valu3::value::Value;
159//!
160//! fn main() {
161//!     let (tx, rx) = channel();
162//!     let mut cache = Quickleaf::with_sender(10, tx);
163//!
164//!     cache.insert("key1", 1);
165//!     cache.insert("key2", 2);
166//!     cache.insert("key3", 3);
167//!
168//!     let mut items = Vec::new();
169//!
170//!     for data in rx {
171//!         items.push(data);
172//!
173//!         if items.len() == 3 {
174//!             break;
175//!         }
176//!     }
177//!
178//!     assert_eq!(items.len(), 3);
179//!     assert_eq!(
180//!         items[0],
181//!         Event::insert("key1".to_string(), 1.to_value())
182//!     );
183//!     assert_eq!(
184//!         items[1],
185//!         Event::insert("key2".to_string(), 2.to_value())
186//!     );
187//!     assert_eq!(
188//!         items[2],
189//!         Event::insert("key3".to_string(), 3.to_value())
190//!     );
191//! }
192//! ```
193//!
194//! ### Event Types
195//!
196//! There are three types of events:
197//!
198//! 1. `Insert`: Triggered when a new entry is inserted into the cache.
199//! 2. `Remove`: Triggered when an entry is removed from the cache.
200//! 3. `Clear`: Triggered when the cache is cleared.
201//!
202//! ## Persistent Storage (Optional)
203//!
204//! Quickleaf supports optional persistent storage using SQLite as a backing store. This feature
205//! provides durability across application restarts while maintaining high-performance in-memory operations.
206//!
207//! ### Enabling Persistence
208//!
209//! Add the `persist` feature to your `Cargo.toml`:
210//!
211//! ```toml
212//! [dependencies]
213//! quickleaf = { version = "0.4", features = ["persist"] }
214//! ```
215//!
216//! ### Basic Persistent Cache
217//!
218//! ```rust,no_run
219//! # #[cfg(feature = "persist")]
220//! # {
221//! use quickleaf::Cache;
222//!
223//! fn main() -> Result<(), Box<dyn std::error::Error>> {
224//!     let mut cache = Cache::with_persist("cache.db", 1000)?;
225//!     
226//!     cache.insert("user:123", "Alice");
227//!     cache.insert("user:456", "Bob");
228//!     
229//!     drop(cache);
230//!     
231//!     let mut cache = Cache::with_persist("cache.db", 1000)?;
232//!     
233//!     println!("{:?}", cache.get("user:123"));
234//!     
235//!     Ok(())
236//! }
237//! # }
238//! ```
239//!
240//! ### Persistent Cache with TTL
241//!
242//! ```rust,no_run
243//! # #[cfg(feature = "persist")]
244//! # {
245//! use quickleaf::{Cache, Duration};
246//!
247//! fn main() -> Result<(), Box<dyn std::error::Error>> {
248//!     let mut cache = Cache::with_persist("cache.db", 1000)?;
249//!     
250//!     
251//!     cache.insert_with_ttl(
252//!         "session:abc",
253//!         "temp_data",
254//!         Duration::from_secs(3600)
255//!     );
256//!     
257//!     Ok(())
258//! }
259//! # }
260//! ```
261//!
262//! ### Persistence with Events
263//!
264//! ```rust,no_run
265//! # #[cfg(feature = "persist")]
266//! # {
267//! use quickleaf::Cache;
268//! use std::sync::mpsc::channel;
269//!
270//! fn main() -> Result<(), Box<dyn std::error::Error>> {
271//!     let (tx, rx) = channel();
272//!     
273//!     let mut cache = Cache::with_persist_and_sender("cache.db", 1000, tx)?;
274//!     
275//!     cache.insert("key1", "value1");
276//!     
277//!     for event in rx.try_iter() {
278//!         println!("Event: {:?}", event);
279//!     }
280//!     
281//!     Ok(())
282//! }
283//! # }
284//! ```
285//!
286//! ### Complete Persistence Stack (SQLite + Events + TTL)
287//!
288//! ```rust,no_run
289//! # #[cfg(feature = "persist")]
290//! # {
291//! use quickleaf::Cache;
292//! use std::sync::mpsc::channel;
293//! use std::time::Duration;
294//!
295//! fn main() -> Result<(), Box<dyn std::error::Error>> {
296//!     let (tx, rx) = channel();
297//!     
298//!     let mut cache = Cache::with_persist_and_sender_and_ttl(
299//!         "full_featured_cache.db",
300//!         1000,
301//!         tx,
302//!         Duration::from_secs(3600)  
303//!     )?;
304//!     
305//!     cache.insert("session", "user_data");
306//!     
307//!     cache.insert_with_ttl("temp", "data", Duration::from_secs(60));
308//!     
309//!     for event in rx.try_iter() {
310//!         println!("Event: {:?}", event);
311//!     }
312//!     
313//!     Ok(())
314//! }
315//! # }
316//! ```
317//!
318//! ### Persistence Features
319//!
320//! - **Automatic Persistence**: All cache operations are automatically persisted to SQLite
321//! - **Background Writer**: Non-blocking write operations using a background thread
322//! - **Crash Recovery**: Automatic recovery from unexpected shutdowns
323//! - **TTL Preservation**: TTL values are preserved across restarts
324//! - **Efficient Storage**: Uses SQLite with optimized indexes for performance
325//! - **Seamless Integration**: Works with all existing Quickleaf features
326
327mod cache;
328mod error;
329mod event;
330mod filter;
331pub mod filters;
332mod list_props;
333#[cfg(test)]
334#[cfg(feature = "persist")]
335mod persist_tests;
336pub mod prelude;
337mod quickleaf;
338#[cfg(feature = "persist")]
339mod sqlite_store;
340#[cfg(test)]
341mod tests;
342#[cfg(test)]
343mod ttl_tests;
344
345pub use cache::{Cache, CacheItem};
346pub use error::Error;
347pub use event::{Event, EventData};
348pub use filter::Filter;
349pub use list_props::{ListProps, Order, StartAfter};
350pub use quickleaf::Quickleaf;
351pub use std::time::Duration;
352pub use valu3;
353pub use valu3::value::Value;