dmsc/cache/
config.rs

1//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
2//!
3//! This file is part of DMSC.
4//! The DMSC project belongs to the Dunimd Team.
5//!
6//! Licensed under the Apache License, Version 2.0 (the "License");
7//! You may not use this file except in compliance with the License.
8//! You may obtain a copy of the License at
9//!
10//!     http://www.apache.org/licenses/LICENSE-2.0
11//!
12//! Unless required by applicable law or agreed to in writing, software
13//! distributed under the License is distributed on an "AS IS" BASIS,
14//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//! See the License for the specific language governing permissions and
16//! limitations under the License.
17
18//! # Cache Configuration Module
19//!
20//! This module defines the configuration structures and types used by the cache system.
21//! It includes main cache configuration, backend type selection, and per-entry cache policies.
22//!
23//! ## Key Components
24//!
25//! - **[`DMSCCacheConfig`](DMSCCacheConfig)**: Main cache configuration structure
26//! - **[`DMSCCacheBackendType`](DMSCCacheBackendType)**: Enum for selecting cache backend type
27//! - **[`DMSCCachePolicy`](DMSCCachePolicy)**: Per-entry cache policy with TTL and size limits
28//!
29//! ## Design Principles
30//!
31//! 1. **Flexibility**: Supports multiple cache backends (Memory, Redis, Hybrid)
32//! 2. **Configurability**: Extensive configuration options for each backend
33//! 3. **Default Values**: Sensible defaults for all configuration parameters
34//! 4. **Type Safety**: Strongly typed configuration with enum-based backend selection
35//! 5. **Serialization**: Built-in JSON/YAML/TOML serialization support
36//! 6. **Policy-Based**: Supports per-entry cache policies
37//!
38//! ## Usage Example
39//!
40//! ```rust,ignore
41//! use dmsc::cache::{DMSCCacheConfig, DMSCCacheBackendType, DMSCCachePolicy};
42//! use std::time::Duration;
43//!
44//! // Create default cache configuration
45//! let default_config = DMSCCacheConfig::default();
46//!
47//! // Create custom cache configuration
48//! let custom_config = DMSCCacheConfig {
49//!     enabled: true,
50//!     default_ttl_secs: 7200, // 2 hours
51//!     max_memory_mb: 1024,
52//!     cleanup_interval_secs: 600, // 10 minutes
53//!     backend_type: DMSCCacheBackendType::Hybrid,
54//!     redis_url: "redis://localhost:6379/1".to_string(),
55//!     redis_pool_size: 20,
56//! };
57//!
58//! // Parse backend type from string
59//! let backend_type: DMSCCacheBackendType = "redis".parse().unwrap();
60//!
61//! // Create a custom cache policy
62//! let cache_policy = DMSCCachePolicy {
63//!     ttl: Some(Duration::from_secs(1800)), // 30 minutes
64//!     refresh_on_access: true,
65//!     max_size: Some(1024 * 1024), // 1MB
66//! };
67//! ```
68
69#![allow(non_snake_case)]
70
71use serde::{Serialize, Deserialize};
72use std::time::Duration;
73
74#[cfg(feature = "pyo3")]
75use pyo3::prelude::*;
76
77/// Main cache configuration structure.
78///
79/// This struct contains all configuration options for the cache system,
80/// including backend selection, TTL settings, memory limits, and cleanup intervals.
81#[derive(Debug, Clone, Serialize, Deserialize)]
82#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass(get_all, set_all))]
83pub struct DMSCCacheConfig {
84    /// Whether caching is enabled
85    pub enabled: bool,
86    /// Default time-to-live in seconds
87    pub default_ttl_secs: u64,
88    /// Maximum memory usage in megabytes
89    pub max_memory_mb: u64,
90    /// Interval for cleaning up expired entries in seconds
91    pub cleanup_interval_secs: u64,
92    /// Type of cache backend to use
93    pub backend_type: DMSCCacheBackendType,
94    /// Redis connection URL (if using Redis or Hybrid backend)
95    pub redis_url: String,
96    /// Redis connection pool size
97    pub redis_pool_size: usize,
98}
99
100impl Default for DMSCCacheConfig {
101    /// Creates a default cache configuration with sensible values.
102    ///
103    /// Default values:
104    /// - enabled: true
105    /// - default_ttl_secs: 3600 (1 hour)
106    /// - max_memory_mb: 512
107    /// - cleanup_interval_secs: 300 (5 minutes)
108    /// - backend_type: Memory
109    /// - redis_url: "redis://127.0.0.1:6379"
110    /// - redis_pool_size: 10
111    ///
112    /// # Returns
113    /// A new `DMSCCacheConfig` instance with default values
114    fn default() -> Self {
115        Self {
116            enabled: true,
117            default_ttl_secs: 3600, // 1 hour
118            max_memory_mb: 512,
119            cleanup_interval_secs: 300, // 5 minutes
120            backend_type: DMSCCacheBackendType::Memory,
121            redis_url: "redis://127.0.0.1:6379".to_string(),
122            redis_pool_size: 10,
123        }
124    }
125}
126
127#[cfg(feature = "pyo3")]
128#[pymethods]
129impl DMSCCacheConfig {
130    #[new]
131    fn py_new() -> Self {
132        Self::default()
133    }
134
135    #[staticmethod]
136    fn default_config() -> Self {
137        Self::default()
138    }
139}
140
141/// Cache backend type enumeration.
142///
143/// Defines the different cache backend types supported by DMSC.
144#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
145#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
146pub enum DMSCCacheBackendType {
147    /// In-memory cache (fast, non-persistent)
148    Memory,
149    /// Redis cache (persistent, distributed)
150    Redis,
151    /// Hybrid cache (Memory + Redis for performance and persistence)
152    Hybrid,
153}
154
155impl DMSCCacheBackendType {
156    /// Converts a string to a `DMSCCacheBackendType`.
157    ///
158    /// This method provides a custom string conversion for cache backend types.
159    ///
160    /// # Parameters
161    ///
162    /// - `s`: String to convert to `DMSCCacheBackendType`
163    ///
164    /// # Returns
165    ///
166    /// A `DMSCCacheBackendType` based on the input string
167    ///
168    /// # Mapping
169    ///
170    /// - "redis" -> `DMSCCacheBackendType::Redis`
171    /// - "hybrid" -> `DMSCCacheBackendType::Hybrid`
172    /// - Any other value -> `DMSCCacheBackendType::Memory`
173    pub fn from_str_custom(s: &str) -> Self {
174        match s.to_lowercase().as_str() {
175            "redis" => DMSCCacheBackendType::Redis,
176            "hybrid" => DMSCCacheBackendType::Hybrid,
177            _ => DMSCCacheBackendType::Memory,
178        }
179    }
180}
181
182/// Implements standard FromStr trait for DMSCCacheBackendType
183impl std::str::FromStr for DMSCCacheBackendType {
184    type Err = ();
185
186    /// Parses a string to a `DMSCCacheBackendType`.
187    ///
188    /// This implementation of the standard `FromStr` trait allows for easy
189    /// parsing of strings to `DMSCCacheBackendType` using the `parse()` method.
190    ///
191    /// # Parameters
192    ///
193    /// - `s`: String to parse
194    ///
195    /// # Returns
196    ///
197    /// `Ok(DMSCCacheBackendType)` if parsing succeeds, otherwise `Ok(DMSCCacheBackendType::Memory)`
198    fn from_str(s: &str) -> Result<Self, Self::Err> {
199        Ok(Self::from_str_custom(s))
200    }
201}
202
203/// Cache policy for individual cache entries.
204///
205/// This struct defines the caching policy for individual cache entries,
206/// including TTL, refresh behavior, and size limits.
207#[derive(Debug, Clone, Serialize, Deserialize)]
208#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass(get_all, set_all))]
209pub struct DMSCCachePolicy {
210    /// Time-to-live for cache entries
211    pub ttl: Option<Duration>,
212    /// Whether to refresh TTL on access
213    pub refresh_on_access: bool,
214    /// Maximum size for cached data in bytes
215    pub max_size: Option<usize>,
216}
217
218impl Default for DMSCCachePolicy {
219    /// Creates a default cache policy with sensible values.
220    ///
221    /// Default values:
222    /// - ttl: Some(Duration::from_secs(3600)) (1 hour)
223    /// - refresh_on_access: false
224    /// - max_size: None (no size limit)
225    ///
226    /// # Returns
227    ///
228    /// A new `DMSCCachePolicy` instance with default values
229    fn default() -> Self {
230        Self {
231            ttl: Some(Duration::from_secs(3600)),
232            refresh_on_access: false,
233            max_size: None,
234        }
235    }
236}
237
238#[cfg(feature = "pyo3")]
239#[pymethods]
240impl DMSCCachePolicy {
241    #[new]
242    fn new() -> Self {
243        Self::default()
244    }
245
246    #[staticmethod]
247    fn default_policy() -> Self {
248        Self::default()
249    }
250}