1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! # Cachelito
//!
//! A lightweight, thread-safe caching library for Rust that provides automatic memoization
//! through procedural macros.
//!
//! ## Features
//!
//! - **Easy to use**: Simply add `#[cache]` attribute to any function or method
//! - **Global scope by default**: Cache shared across all threads (use `scope = "thread"` for thread-local)
//! - **High-performance synchronization**: Uses `parking_lot::RwLock` for global caches
//! - **Thread-local option**: Optional thread-local storage for maximum performance
//! - **Multiple eviction policies**: FIFO, LRU, LFU, ARC, Random, and TLRU
//! - **TLRU with frequency_weight**: Fine-tune recency vs frequency balance (v0.15.0)
//! - **Flexible key generation**: Supports custom cache key implementations
//! - **Result-aware**: Intelligently caches only successful `Result::Ok` values
//! - **Cache limits**: Control size with `limit` (entry count) or `max_memory` (memory-based)
//! - **TTL support**: Time-to-live expiration for automatic cache invalidation
//! - **Statistics**: Track hit/miss rates via `stats` feature
//! - **Smart invalidation**: Tag-based, event-driven, and conditional invalidation
//! - **Conditional caching**: Cache only valid results with `cache_if` predicates
//! - **Type-safe**: Full compile-time type checking
//!
//! ## Quick Start
//!
//! Add the `#[cache]` attribute to any function you want to memoize:
//!
//! ```rust
//! use cachelito::cache;
//!
//! #[cache]
//! fn fibonacci(n: u32) -> u64 {
//! if n <= 1 {
//! return n as u64;
//! }
//! fibonacci(n - 1) + fibonacci(n - 2)
//! }
//!
//! // First call computes the result
//! let result1 = fibonacci(10);
//! // Second call returns cached result instantly
//! let result2 = fibonacci(10);
//! assert_eq!(result1, result2);
//! ```
//!
//! ## Custom Cache Keys
//!
//! For complex types, you can implement custom cache key generation:
//!
//! ```rust
//! use cachelito::cache;
//! use cachelito_core::{CacheableKey, DefaultCacheableKey};
//!
//! #[derive(Debug, Clone)]
//! struct User {
//! id: u64,
//! name: String,
//! }
//!
//! // Option 1: Use default Debug-based key
//! impl DefaultCacheableKey for User {}
//!
//! // Note: You can also implement CacheableKey directly instead of DefaultCacheableKey
//! // for better performance, but not both at the same time
//! ```
//!
//! Or with a custom implementation:
//!
//! ```rust
//! use cachelito::cache;
//! use cachelito_core::CacheableKey;
//!
//! #[derive(Debug, Clone)]
//! struct UserId {
//! id: u64,
//! name: String,
//! }
//!
//! // Custom key implementation (more efficient than Debug-based)
//! impl CacheableKey for UserId {
//! fn to_cache_key(&self) -> String {
//! format!("user:{}", self.id)
//! }
//! }
//! ```
//!
//! ## Caching with Methods
//!
//! The `#[cache]` attribute also works with methods:
//!
//! ```rust
//! use cachelito::cache;
//! use cachelito_core::DefaultCacheableKey;
//!
//! #[derive(Debug, Clone)]
//! struct Calculator;
//!
//! impl DefaultCacheableKey for Calculator {}
//!
//! impl Calculator {
//! #[cache]
//! fn add(&self, a: i32, b: i32) -> i32 {
//! a + b
//! }
//! }
//! ```
//!
//! ## Error Handling
//!
//! Functions returning `Result<T, E>` only cache successful results:
//!
//! ```rust
//! use cachelito::cache;
//!
//! #[cache]
//! fn divide(a: i32, b: i32) -> Result<i32, String> {
//! if b == 0 {
//! Err("Division by zero".to_string())
//! } else {
//! Ok(a / b)
//! }
//! }
//!
//! // Ok results are cached
//! let _ = divide(10, 2);
//! // Err results are NOT cached
//! let _ = divide(10, 0);
//! ```
pub use *;
pub use cache;