1use std::time::Duration;
2
3#[derive(Debug, Clone)]
23pub struct RetryConfig {
24 pub(crate) max_attempts: u8,
25 pub(crate) initial_backoff: Duration,
26 pub(crate) max_backoff: Duration,
27 pub(crate) reduce_chunk_on_retry: bool,
28 pub(crate) min_sectors_per_read: u32,
29}
30
31impl RetryConfig {
32 pub fn with_max_attempts(mut self, attempts: u8) -> Self {
36 self.max_attempts = attempts.max(1);
37 self
38 }
39
40 pub fn with_initial_backoff(mut self, backoff: Duration) -> Self {
44 self.initial_backoff = backoff;
45 self
46 }
47
48 pub fn with_max_backoff(mut self, backoff: Duration) -> Self {
52 self.max_backoff = backoff;
53 self
54 }
55
56 pub fn with_chunk_reduction(mut self, enabled: bool) -> Self {
58 self.reduce_chunk_on_retry = enabled;
59 self
60 }
61
62 pub fn with_min_sectors_per_read(mut self, sectors: u32) -> Self {
66 self.min_sectors_per_read = sectors.max(1);
67 self
68 }
69}
70
71impl Default for RetryConfig {
72 fn default() -> Self {
73 Self {
74 max_attempts: 4,
75 initial_backoff: Duration::from_millis(20),
76 max_backoff: Duration::from_millis(300),
77 reduce_chunk_on_retry: true,
78 min_sectors_per_read: 1,
79 }
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn default_policy_matches_documented_values() {
89 let config = RetryConfig::default();
90
91 assert_eq!(config.max_attempts, 4);
92 assert_eq!(config.initial_backoff, Duration::from_millis(20));
93 assert_eq!(config.max_backoff, Duration::from_millis(300));
94 assert!(config.reduce_chunk_on_retry);
95 assert_eq!(config.min_sectors_per_read, 1);
96 }
97
98 #[test]
99 fn builders_override_and_normalize_values() {
100 let config = RetryConfig::default()
101 .with_max_attempts(0)
102 .with_initial_backoff(Duration::from_millis(50))
103 .with_max_backoff(Duration::from_secs(1))
104 .with_chunk_reduction(false)
105 .with_min_sectors_per_read(0);
106
107 assert_eq!(config.max_attempts, 1);
108 assert_eq!(config.initial_backoff, Duration::from_millis(50));
109 assert_eq!(config.max_backoff, Duration::from_secs(1));
110 assert!(!config.reduce_chunk_on_retry);
111 assert_eq!(config.min_sectors_per_read, 1);
112 }
113}