chie_shared/config/
storage.rs

1//! Storage configuration
2
3use serde::{Deserialize, Serialize};
4
5/// Storage configuration
6///
7/// # Examples
8///
9/// Using the default configuration:
10/// ```
11/// use chie_shared::StorageConfig;
12///
13/// let config = StorageConfig::default();
14/// assert_eq!(config.data_dir, "./chie_data");
15/// assert_eq!(config.max_cache_size_bytes, 10 * 1024 * 1024 * 1024); // 10 GB
16/// assert!(config.enable_persistence);
17/// assert!(config.enable_compression);
18/// assert!(config.validate().is_ok());
19/// ```
20///
21/// Building a custom configuration:
22/// ```
23/// use chie_shared::StorageConfigBuilder;
24///
25/// let config = StorageConfigBuilder::new()
26///     .data_dir("/var/lib/chie")
27///     .max_cache_size_gb(50)
28///     .enable_persistence(true)
29///     .enable_compression(true)
30///     .sync_interval_secs(600)  // 10 minutes
31///     .gc_interval_secs(7200)   // 2 hours
32///     .build();
33///
34/// assert_eq!(config.data_dir, "/var/lib/chie");
35/// assert_eq!(config.max_cache_size_bytes, 50 * 1024 * 1024 * 1024);
36/// assert_eq!(config.sync_interval_secs, 600);
37/// ```
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct StorageConfig {
40    /// Path to storage directory
41    pub data_dir: String,
42    /// Maximum cache size in bytes
43    pub max_cache_size_bytes: u64,
44    /// Enable disk persistence
45    pub enable_persistence: bool,
46    /// Sync interval in seconds (0 = no auto-sync)
47    pub sync_interval_secs: u64,
48    /// Enable compression
49    pub enable_compression: bool,
50    /// Garbage collection interval in seconds
51    pub gc_interval_secs: u64,
52}
53
54impl Default for StorageConfig {
55    fn default() -> Self {
56        Self {
57            data_dir: "./chie_data".to_string(),
58            max_cache_size_bytes: 10 * 1024 * 1024 * 1024, // 10 GB
59            enable_persistence: true,
60            sync_interval_secs: 300, // 5 minutes
61            enable_compression: true,
62            gc_interval_secs: 3600, // 1 hour
63        }
64    }
65}
66
67impl StorageConfig {
68    /// Validate the storage configuration
69    ///
70    /// # Errors
71    ///
72    /// Returns error if configuration is invalid
73    pub fn validate(&self) -> crate::ChieResult<()> {
74        use crate::ChieError;
75
76        if self.data_dir.is_empty() {
77            return Err(ChieError::validation("data_dir must not be empty"));
78        }
79
80        if self.max_cache_size_bytes == 0 {
81            return Err(ChieError::validation(
82                "max_cache_size_bytes must be greater than 0",
83            ));
84        }
85
86        Ok(())
87    }
88}
89
90/// Builder for `StorageConfig`
91///
92/// # Examples
93///
94/// Building a high-capacity storage configuration:
95/// ```
96/// use chie_shared::StorageConfigBuilder;
97///
98/// let config = StorageConfigBuilder::new()
99///     .data_dir("/mnt/storage/chie")
100///     .max_cache_size_gb(100)
101///     .enable_persistence(true)
102///     .enable_compression(true)
103///     .build();
104///
105/// assert_eq!(config.max_cache_size_bytes, 100 * 1024 * 1024 * 1024);
106/// assert!(config.validate().is_ok());
107/// ```
108///
109/// Building a memory-only configuration (no persistence):
110/// ```
111/// use chie_shared::StorageConfigBuilder;
112///
113/// let config = StorageConfigBuilder::new()
114///     .data_dir("/tmp/chie")
115///     .max_cache_size_gb(5)
116///     .enable_persistence(false)
117///     .sync_interval_secs(0)  // No auto-sync
118///     .build();
119///
120/// assert!(!config.enable_persistence);
121/// assert_eq!(config.sync_interval_secs, 0);
122/// ```
123#[derive(Debug, Default)]
124pub struct StorageConfigBuilder {
125    config: StorageConfig,
126}
127
128impl StorageConfigBuilder {
129    /// Create a new builder with default values
130    #[must_use]
131    pub fn new() -> Self {
132        Self::default()
133    }
134
135    /// Set data directory
136    #[must_use]
137    pub fn data_dir(mut self, dir: impl Into<String>) -> Self {
138        self.config.data_dir = dir.into();
139        self
140    }
141
142    /// Set maximum cache size in bytes
143    #[must_use]
144    pub const fn max_cache_size_bytes(mut self, size: u64) -> Self {
145        self.config.max_cache_size_bytes = size;
146        self
147    }
148
149    /// Set maximum cache size in GB
150    #[must_use]
151    pub const fn max_cache_size_gb(mut self, size: u64) -> Self {
152        self.config.max_cache_size_bytes = size * 1024 * 1024 * 1024;
153        self
154    }
155
156    /// Enable or disable persistence
157    #[must_use]
158    pub const fn enable_persistence(mut self, enable: bool) -> Self {
159        self.config.enable_persistence = enable;
160        self
161    }
162
163    /// Set sync interval in seconds
164    #[must_use]
165    pub const fn sync_interval_secs(mut self, interval: u64) -> Self {
166        self.config.sync_interval_secs = interval;
167        self
168    }
169
170    /// Enable or disable compression
171    #[must_use]
172    pub const fn enable_compression(mut self, enable: bool) -> Self {
173        self.config.enable_compression = enable;
174        self
175    }
176
177    /// Set garbage collection interval in seconds
178    #[must_use]
179    pub const fn gc_interval_secs(mut self, interval: u64) -> Self {
180        self.config.gc_interval_secs = interval;
181        self
182    }
183
184    /// Build the configuration
185    #[must_use]
186    pub fn build(self) -> StorageConfig {
187        self.config
188    }
189}