mockforge_vbr/
config.rs

1//! VBR engine configuration
2//!
3//! This module defines the configuration structure for the Virtual Backend Reality engine,
4//! including storage backend selection, entity definitions, session configuration, and
5//! time-based data evolution settings.
6
7use serde::{Deserialize, Serialize};
8use std::path::PathBuf;
9
10/// Storage backend type for the virtual database
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
12#[serde(tag = "backend", rename_all = "lowercase")]
13pub enum StorageBackend {
14    /// SQLite database backend (persistent, production-like)
15    Sqlite {
16        /// Path to the SQLite database file
17        path: PathBuf,
18    },
19    /// JSON file backend (human-readable, easy to inspect)
20    Json {
21        /// Path to the JSON file
22        path: PathBuf,
23    },
24    /// In-memory backend (fast, no persistence)
25    Memory,
26}
27
28impl Default for StorageBackend {
29    fn default() -> Self {
30        StorageBackend::Sqlite {
31            path: PathBuf::from("./data/vbr.db"),
32        }
33    }
34}
35
36/// Session configuration
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct SessionConfig {
39    /// Whether sessions are enabled
40    #[serde(default = "default_true")]
41    pub enabled: bool,
42
43    /// Session timeout in seconds
44    #[serde(default = "default_session_timeout")]
45    pub timeout: u64,
46
47    /// Whether to use session-scoped data (per-session virtual DB)
48    #[serde(default)]
49    pub scoped_data: bool,
50}
51
52fn default_true() -> bool {
53    true
54}
55
56fn default_session_timeout() -> u64 {
57    3600 // 1 hour
58}
59
60impl Default for SessionConfig {
61    fn default() -> Self {
62        Self {
63            enabled: true,
64            timeout: default_session_timeout(),
65            scoped_data: false,
66        }
67    }
68}
69
70/// Data aging configuration
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct AgingConfig {
73    /// Whether data aging is enabled
74    #[serde(default)]
75    pub enabled: bool,
76
77    /// Cleanup interval in seconds
78    #[serde(default = "default_cleanup_interval")]
79    pub cleanup_interval: u64,
80
81    /// Whether to automatically update timestamp fields
82    #[serde(default = "default_true")]
83    pub auto_update_timestamps: bool,
84}
85
86fn default_cleanup_interval() -> u64 {
87    3600 // 1 hour
88}
89
90impl Default for AgingConfig {
91    fn default() -> Self {
92        Self {
93            enabled: false,
94            cleanup_interval: default_cleanup_interval(),
95            auto_update_timestamps: true,
96        }
97    }
98}
99
100/// Authentication configuration
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct AuthConfig {
103    /// Whether authentication is enabled
104    #[serde(default)]
105    pub enabled: bool,
106
107    /// JWT secret for token generation
108    #[serde(default)]
109    pub jwt_secret: Option<String>,
110
111    /// Token expiration in seconds
112    #[serde(default = "default_token_expiration")]
113    pub token_expiration: u64,
114}
115
116fn default_token_expiration() -> u64 {
117    86400 // 24 hours
118}
119
120impl Default for AuthConfig {
121    fn default() -> Self {
122        Self {
123            enabled: false,
124            jwt_secret: None,
125            token_expiration: default_token_expiration(),
126        }
127    }
128}
129
130/// VBR engine configuration
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct VbrConfig {
133    /// Storage backend configuration
134    #[serde(default)]
135    pub storage: StorageBackend,
136
137    /// Session configuration
138    #[serde(default)]
139    pub sessions: SessionConfig,
140
141    /// Data aging configuration
142    #[serde(default)]
143    pub aging: AgingConfig,
144
145    /// Authentication configuration
146    #[serde(default)]
147    pub auth: AuthConfig,
148
149    /// API base path prefix
150    #[serde(default = "default_api_prefix")]
151    pub api_prefix: String,
152}
153
154fn default_api_prefix() -> String {
155    "/api".to_string()
156}
157
158impl Default for VbrConfig {
159    fn default() -> Self {
160        Self {
161            storage: StorageBackend::default(),
162            sessions: SessionConfig::default(),
163            aging: AgingConfig::default(),
164            auth: AuthConfig::default(),
165            api_prefix: default_api_prefix(),
166        }
167    }
168}
169
170impl VbrConfig {
171    /// Create a new VBR configuration with default settings
172    pub fn new() -> Self {
173        Self::default()
174    }
175
176    /// Set the storage backend
177    pub fn with_storage_backend(mut self, backend: StorageBackend) -> Self {
178        self.storage = backend;
179        self
180    }
181
182    /// Set session configuration
183    pub fn with_sessions(mut self, config: SessionConfig) -> Self {
184        self.sessions = config;
185        self
186    }
187
188    /// Set aging configuration
189    pub fn with_aging(mut self, config: AgingConfig) -> Self {
190        self.aging = config;
191        self
192    }
193
194    /// Set authentication configuration
195    pub fn with_auth(mut self, config: AuthConfig) -> Self {
196        self.auth = config;
197        self
198    }
199
200    /// Set the API prefix
201    pub fn with_api_prefix(mut self, prefix: String) -> Self {
202        self.api_prefix = prefix;
203        self
204    }
205}
206
207#[cfg(test)]
208mod tests {
209    use super::*;
210
211    #[test]
212    fn test_storage_backend_default() {
213        let backend = StorageBackend::default();
214        assert!(matches!(backend, StorageBackend::Sqlite { .. }));
215    }
216
217    #[test]
218    fn test_vbr_config_default() {
219        let config = VbrConfig::default();
220        assert!(config.sessions.enabled);
221        assert_eq!(config.sessions.timeout, 3600);
222        assert!(!config.aging.enabled);
223        assert!(!config.auth.enabled);
224        assert_eq!(config.api_prefix, "/api");
225    }
226
227    #[test]
228    fn test_vbr_config_builder() {
229        let config = VbrConfig::new()
230            .with_api_prefix("/v1/api".to_string())
231            .with_storage_backend(StorageBackend::Memory);
232
233        assert_eq!(config.api_prefix, "/v1/api");
234        assert!(matches!(config.storage, StorageBackend::Memory));
235    }
236}