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}