reinhardt_db/pool/
config.rs1#[non_exhaustive]
4#[derive(Debug, Clone)]
5pub struct PoolConfig {
7 pub max_size: u32,
9 pub min_idle: Option<u32>,
11 pub max_lifetime: Option<std::time::Duration>,
13 pub idle_timeout: Option<std::time::Duration>,
15 pub connect_timeout: std::time::Duration,
17 pub max_connections: u32,
19 pub min_connections: u32,
21 pub acquire_timeout: std::time::Duration,
23 pub test_before_acquire: bool,
25}
26
27impl Default for PoolConfig {
28 fn default() -> Self {
29 Self {
30 max_size: 10,
31 min_idle: None,
32 max_lifetime: Some(std::time::Duration::from_secs(1800)),
33 idle_timeout: Some(std::time::Duration::from_secs(600)),
34 connect_timeout: std::time::Duration::from_secs(30),
35 max_connections: 10,
36 min_connections: 1,
37 acquire_timeout: std::time::Duration::from_secs(30),
38 test_before_acquire: false,
39 }
40 }
41}
42
43impl PoolConfig {
44 pub fn new() -> Self {
55 Self::default()
56 }
57
58 pub fn with_max_connections(mut self, max: u32) -> Self {
60 self.max_connections = max;
61 self
62 }
63
64 pub fn with_min_connections(mut self, min: u32) -> Self {
66 self.min_connections = min;
67 self
68 }
69
70 pub fn with_connection_timeout(mut self, timeout: std::time::Duration) -> Self {
72 self.connect_timeout = timeout;
73 self
74 }
75
76 pub fn with_connect_timeout(mut self, timeout: std::time::Duration) -> Self {
78 self.connect_timeout = timeout;
79 self
80 }
81
82 pub fn with_acquire_timeout(mut self, timeout: std::time::Duration) -> Self {
84 self.acquire_timeout = timeout;
85 self
86 }
87
88 pub fn with_max_lifetime(mut self, lifetime: Option<std::time::Duration>) -> Self {
90 self.max_lifetime = lifetime;
91 self
92 }
93
94 pub fn with_idle_timeout(mut self, timeout: Option<std::time::Duration>) -> Self {
96 self.idle_timeout = timeout;
97 self
98 }
99
100 pub fn with_test_before_acquire(mut self, test: bool) -> Self {
102 self.test_before_acquire = test;
103 self
104 }
105
106 pub fn validate(&self) -> Result<(), String> {
108 if self.max_connections < self.min_connections {
109 return Err("max_connections must be >= min_connections".to_string());
110 }
111 Ok(())
112 }
113}
114
115#[non_exhaustive]
116#[derive(Debug, Clone, Default)]
117pub struct PoolOptions {
119 pub config: PoolConfig,
121}
122
123impl PoolOptions {
124 pub fn new() -> Self {
126 Self::default()
127 }
128
129 pub fn max_size(mut self, max_size: u32) -> Self {
131 self.config.max_size = max_size;
132 self
133 }
134
135 pub fn min_idle(mut self, min_idle: u32) -> Self {
137 self.config.min_idle = Some(min_idle);
138 self
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145 use std::time::Duration;
146
147 #[test]
148 fn default_config_preserves_all_pool_limits() {
149 let config = PoolConfig::default();
150
151 assert_eq!(config.max_size, 10);
152 assert_eq!(config.min_idle, None);
153 assert_eq!(config.max_lifetime, Some(Duration::from_secs(1800)));
154 assert_eq!(config.idle_timeout, Some(Duration::from_secs(600)));
155 assert_eq!(config.connect_timeout, Duration::from_secs(30));
156 assert_eq!(config.max_connections, 10);
157 assert_eq!(config.min_connections, 1);
158 assert_eq!(config.acquire_timeout, Duration::from_secs(30));
159 assert!(!config.test_before_acquire);
160 }
161
162 #[test]
163 fn builder_chain_updates_every_supported_setting() {
164 let connection_timeout_config =
165 PoolConfig::new().with_connection_timeout(Duration::from_secs(15));
166
167 assert_eq!(
168 connection_timeout_config.connect_timeout,
169 Duration::from_secs(15)
170 );
171
172 let config = PoolConfig::new()
173 .with_max_connections(12)
174 .with_min_connections(4)
175 .with_connection_timeout(Duration::from_secs(15))
176 .with_connect_timeout(Duration::from_secs(20))
177 .with_acquire_timeout(Duration::from_secs(25))
178 .with_max_lifetime(Some(Duration::from_secs(3600)))
179 .with_idle_timeout(Some(Duration::from_secs(900)))
180 .with_test_before_acquire(true);
181
182 assert_eq!(config.max_size, 10);
183 assert_eq!(config.min_idle, None);
184 assert_eq!(config.max_lifetime, Some(Duration::from_secs(3600)));
185 assert_eq!(config.idle_timeout, Some(Duration::from_secs(900)));
186 assert_eq!(config.connect_timeout, Duration::from_secs(20));
187 assert_eq!(config.max_connections, 12);
188 assert_eq!(config.min_connections, 4);
189 assert_eq!(config.acquire_timeout, Duration::from_secs(25));
190 assert!(config.test_before_acquire);
191 }
192
193 #[test]
194 fn validation_accepts_equal_connection_bounds() {
195 let config = PoolConfig::new()
196 .with_max_connections(5)
197 .with_min_connections(5);
198
199 assert_eq!(config.validate(), Ok(()));
200 }
201
202 #[test]
203 fn validation_rejects_minimum_above_maximum() {
204 let config = PoolConfig::new()
205 .with_max_connections(4)
206 .with_min_connections(5);
207
208 assert_eq!(
209 config.validate(),
210 Err("max_connections must be >= min_connections".to_string())
211 );
212 }
213
214 #[test]
215 fn options_builder_preserves_all_other_config_defaults() {
216 let options = PoolOptions::new().max_size(20).min_idle(3);
217 let config = options.config;
218
219 assert_eq!(config.max_size, 20);
220 assert_eq!(config.min_idle, Some(3));
221 assert_eq!(config.max_lifetime, Some(Duration::from_secs(1800)));
222 assert_eq!(config.idle_timeout, Some(Duration::from_secs(600)));
223 assert_eq!(config.connect_timeout, Duration::from_secs(30));
224 assert_eq!(config.max_connections, 10);
225 assert_eq!(config.min_connections, 1);
226 assert_eq!(config.acquire_timeout, Duration::from_secs(30));
227 assert!(!config.test_before_acquire);
228 }
229}