Skip to main content

noxu_db/
sequence_config.rs

1//! Sequence configuration.
2//!
3
4/// Specifies the attributes of a sequence.
5///
6///
7#[derive(Debug, Clone)]
8pub struct SequenceConfig {
9    /// Number of elements cached in the sequence handle (default 20).
10    ///
11    /// default is 0 but the task specifies 20 as the noxu default for
12    /// pre-fetching.  A value of 0 disables caching (every get hits the DB).
13    pub cache_size: i32,
14
15    /// Minimum value for the sequence (default i64::MIN).
16    pub range_min: i64,
17
18    /// Maximum value for the sequence (default i64::MAX).
19    pub range_max: i64,
20
21    /// Initial value when the sequence is first created (default 0).
22    pub initial_value: i64,
23
24    /// Create the sequence if it does not exist (default false).
25    pub allow_create: bool,
26
27    /// The sequence counts downward when true (default false — counts upward).
28    pub decrement: bool,
29
30    /// Fail if the sequence already exists (default false).
31    pub exclusive_create: bool,
32
33    /// Wrap around when the range limit is reached (default false).
34    pub wrap: bool,
35}
36
37impl SequenceConfig {
38    /// Creates a `SequenceConfig` with all defaults.
39    pub fn new() -> Self {
40        Self {
41            cache_size: 20,
42            range_min: i64::MIN,
43            range_max: i64::MAX,
44            initial_value: 0,
45            allow_create: false,
46            decrement: false,
47            exclusive_create: false,
48            wrap: false,
49        }
50    }
51
52    /// Sets the number of cached elements.
53    pub fn with_cache_size(mut self, cache_size: i32) -> Self {
54        self.cache_size = cache_size;
55        self
56    }
57
58    /// Sets the sequence range.
59    pub fn with_range(mut self, min: i64, max: i64) -> Self {
60        self.range_min = min;
61        self.range_max = max;
62        self
63    }
64
65    /// Sets the minimum value of the range.
66    pub fn with_range_min(mut self, min: i64) -> Self {
67        self.range_min = min;
68        self
69    }
70
71    /// Sets the maximum value of the range.
72    pub fn with_range_max(mut self, max: i64) -> Self {
73        self.range_max = max;
74        self
75    }
76
77    /// Sets the initial value (only effective on creation).
78    pub fn with_initial_value(mut self, initial_value: i64) -> Self {
79        self.initial_value = initial_value;
80        self
81    }
82
83    /// Configures whether the sequence is created if missing.
84    pub fn with_allow_create(mut self, allow_create: bool) -> Self {
85        self.allow_create = allow_create;
86        self
87    }
88
89    /// Configures whether the sequence decrements instead of incrementing.
90    pub fn with_decrement(mut self, decrement: bool) -> Self {
91        self.decrement = decrement;
92        self
93    }
94
95    /// Configures whether to fail when the sequence already exists.
96    pub fn with_exclusive_create(mut self, exclusive_create: bool) -> Self {
97        self.exclusive_create = exclusive_create;
98        self
99    }
100
101    /// Configures whether to wrap around at the range boundary.
102    pub fn with_wrap(mut self, wrap: bool) -> Self {
103        self.wrap = wrap;
104        self
105    }
106}
107
108impl Default for SequenceConfig {
109    fn default() -> Self {
110        Self::new()
111    }
112}
113
114#[cfg(test)]
115mod tests {
116    use super::*;
117
118    #[test]
119    fn test_default_values() {
120        let cfg = SequenceConfig::new();
121        assert_eq!(cfg.cache_size, 20);
122        assert_eq!(cfg.range_min, i64::MIN);
123        assert_eq!(cfg.range_max, i64::MAX);
124        assert_eq!(cfg.initial_value, 0);
125        assert!(!cfg.allow_create);
126        assert!(!cfg.decrement);
127        assert!(!cfg.exclusive_create);
128        assert!(!cfg.wrap);
129    }
130
131    #[test]
132    fn test_default_trait() {
133        let cfg = SequenceConfig::default();
134        assert_eq!(cfg.cache_size, 20);
135        assert_eq!(cfg.initial_value, 0);
136    }
137
138    #[test]
139    fn test_with_cache_size() {
140        let cfg = SequenceConfig::new().with_cache_size(100);
141        assert_eq!(cfg.cache_size, 100);
142    }
143
144    #[test]
145    fn test_with_cache_size_zero() {
146        // Zero means no caching
147        let cfg = SequenceConfig::new().with_cache_size(0);
148        assert_eq!(cfg.cache_size, 0);
149    }
150
151    #[test]
152    fn test_with_range() {
153        let cfg = SequenceConfig::new().with_range(1, 1000);
154        assert_eq!(cfg.range_min, 1);
155        assert_eq!(cfg.range_max, 1000);
156    }
157
158    #[test]
159    fn test_with_range_min() {
160        let cfg = SequenceConfig::new().with_range_min(42);
161        assert_eq!(cfg.range_min, 42);
162        // range_max should remain default
163        assert_eq!(cfg.range_max, i64::MAX);
164    }
165
166    #[test]
167    fn test_with_range_max() {
168        let cfg = SequenceConfig::new().with_range_max(999);
169        assert_eq!(cfg.range_max, 999);
170        // range_min should remain default
171        assert_eq!(cfg.range_min, i64::MIN);
172    }
173
174    #[test]
175    fn test_with_range_negative() {
176        let cfg = SequenceConfig::new().with_range(-100, -1);
177        assert_eq!(cfg.range_min, -100);
178        assert_eq!(cfg.range_max, -1);
179    }
180
181    #[test]
182    fn test_with_initial_value() {
183        let cfg = SequenceConfig::new().with_initial_value(500);
184        assert_eq!(cfg.initial_value, 500);
185    }
186
187    #[test]
188    fn test_with_initial_value_negative() {
189        let cfg = SequenceConfig::new().with_initial_value(-50);
190        assert_eq!(cfg.initial_value, -50);
191    }
192
193    #[test]
194    fn test_with_allow_create_true() {
195        let cfg = SequenceConfig::new().with_allow_create(true);
196        assert!(cfg.allow_create);
197    }
198
199    #[test]
200    fn test_with_allow_create_false() {
201        let cfg = SequenceConfig::new()
202            .with_allow_create(true)
203            .with_allow_create(false);
204        assert!(!cfg.allow_create);
205    }
206
207    #[test]
208    fn test_with_decrement_true() {
209        let cfg = SequenceConfig::new().with_decrement(true);
210        assert!(cfg.decrement);
211    }
212
213    #[test]
214    fn test_with_decrement_false() {
215        let cfg =
216            SequenceConfig::new().with_decrement(true).with_decrement(false);
217        assert!(!cfg.decrement);
218    }
219
220    #[test]
221    fn test_with_exclusive_create_true() {
222        let cfg = SequenceConfig::new().with_exclusive_create(true);
223        assert!(cfg.exclusive_create);
224    }
225
226    #[test]
227    fn test_with_exclusive_create_false() {
228        let cfg = SequenceConfig::new()
229            .with_exclusive_create(true)
230            .with_exclusive_create(false);
231        assert!(!cfg.exclusive_create);
232    }
233
234    #[test]
235    fn test_with_wrap_true() {
236        let cfg = SequenceConfig::new().with_wrap(true);
237        assert!(cfg.wrap);
238    }
239
240    #[test]
241    fn test_with_wrap_false() {
242        let cfg = SequenceConfig::new().with_wrap(true).with_wrap(false);
243        assert!(!cfg.wrap);
244    }
245
246    #[test]
247    fn test_builder_chain_full() {
248        let cfg = SequenceConfig::new()
249            .with_cache_size(50)
250            .with_range(0, 10_000)
251            .with_initial_value(1)
252            .with_allow_create(true)
253            .with_wrap(true)
254            .with_decrement(false)
255            .with_exclusive_create(false);
256
257        assert_eq!(cfg.cache_size, 50);
258        assert_eq!(cfg.range_min, 0);
259        assert_eq!(cfg.range_max, 10_000);
260        assert_eq!(cfg.initial_value, 1);
261        assert!(cfg.allow_create);
262        assert!(cfg.wrap);
263        assert!(!cfg.decrement);
264        assert!(!cfg.exclusive_create);
265    }
266
267    #[test]
268    fn test_builder_chain_decrement_sequence() {
269        // Typical decrementing sequence: high-to-low range, starts at max
270        let cfg = SequenceConfig::new()
271            .with_range(-1000, 0)
272            .with_initial_value(0)
273            .with_decrement(true)
274            .with_wrap(true)
275            .with_allow_create(true);
276
277        assert_eq!(cfg.range_min, -1000);
278        assert_eq!(cfg.range_max, 0);
279        assert_eq!(cfg.initial_value, 0);
280        assert!(cfg.decrement);
281        assert!(cfg.wrap);
282        assert!(cfg.allow_create);
283    }
284
285    #[test]
286    fn test_with_range_overrides_individual_setters() {
287        // with_range sets both min and max atomically
288        let cfg = SequenceConfig::new()
289            .with_range_min(5)
290            .with_range_max(50)
291            .with_range(100, 200); // overrides both
292        assert_eq!(cfg.range_min, 100);
293        assert_eq!(cfg.range_max, 200);
294    }
295
296    #[test]
297    fn test_clone() {
298        let original = SequenceConfig::new()
299            .with_cache_size(10)
300            .with_range(1, 100)
301            .with_allow_create(true);
302        let cloned = original;
303        assert_eq!(cloned.cache_size, 10);
304        assert_eq!(cloned.range_min, 1);
305        assert_eq!(cloned.range_max, 100);
306        assert!(cloned.allow_create);
307    }
308
309    #[test]
310    fn test_debug() {
311        let cfg = SequenceConfig::new();
312        let s = format!("{:?}", cfg);
313        assert!(s.contains("SequenceConfig"));
314        assert!(s.contains("cache_size"));
315    }
316}