focus_tracker_core/
config.rs1use std::time::Duration;
2
3#[derive(Debug, Clone)]
5pub struct IconConfig {
6 pub size: Option<u32>,
9
10 pub filter_type: image::imageops::FilterType,
12}
13
14impl Default for IconConfig {
15 fn default() -> Self {
16 Self {
17 size: None,
18 filter_type: image::imageops::FilterType::Lanczos3,
19 }
20 }
21}
22
23impl IconConfig {
24 pub fn new() -> Self {
26 Self::default()
27 }
28
29 pub fn with_size(mut self, size: u32) -> Self {
37 self.validate_size(size);
38 self.size = Some(size);
39 self
40 }
41
42 pub fn get_size_or_default(&self) -> u32 {
44 self.size.unwrap_or(128) }
46
47 fn validate_size(&self, size: u32) {
49 if size == 0 {
50 panic!("Icon size cannot be zero");
51 }
52 if size > 512 {
53 panic!("Icon size cannot be greater than 512 pixels");
54 }
55 }
56}
57
58#[derive(Debug, Clone)]
60pub struct FocusTrackerConfig {
61 pub poll_interval: Duration,
64 pub icon: IconConfig,
67}
68
69impl Default for FocusTrackerConfig {
70 fn default() -> Self {
71 Self {
72 poll_interval: Duration::from_millis(100),
73 icon: IconConfig::default(),
74 }
75 }
76}
77
78impl FocusTrackerConfig {
79 pub fn new() -> Self {
81 Self::default()
82 }
83
84 pub fn with_icon_config(mut self, icon: IconConfig) -> Self {
89 self.icon = icon;
90 self
91 }
92
93 pub fn with_icon_size(mut self, size: u32) -> Self {
101 self.icon = self.icon.with_size(size);
102 self
103 }
104
105 pub fn with_poll_interval(mut self, interval: Duration) -> Self {
113 self.validate_poll_interval(interval);
114 self.poll_interval = interval;
115 self
116 }
117
118 pub fn with_poll_interval_ms(self, ms: u64) -> Self {
126 self.with_poll_interval(Duration::from_millis(ms))
127 }
128
129 fn validate_poll_interval(&self, interval: Duration) {
131 if interval.is_zero() {
132 panic!("Poll interval cannot be zero");
133 }
134 if interval > Duration::from_secs(10) {
135 panic!("Poll interval cannot be greater than 10 seconds");
136 }
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143
144 #[test]
145 fn test_default_config() {
146 let config = FocusTrackerConfig::default();
147 assert_eq!(config.poll_interval, Duration::from_millis(100));
148 }
149
150 #[test]
151 fn test_default_icon_config() {
152 let config = FocusTrackerConfig::default();
153 assert_eq!(config.icon.size, None);
154 }
155
156 #[test]
157 fn test_builder_pattern() {
158 let config = FocusTrackerConfig::new().with_poll_interval_ms(250);
159 assert_eq!(config.poll_interval, Duration::from_millis(250));
160 }
161
162 #[test]
163 fn test_icon_config_builder() {
164 let config = FocusTrackerConfig::new().with_icon_size(64);
165 assert_eq!(config.icon.size, Some(64));
166 }
167
168 #[test]
169 fn test_icon_config_default_size() {
170 let icon_config = IconConfig::new();
171 assert_eq!(icon_config.get_size_or_default(), 128);
172 }
173
174 #[test]
175 fn test_icon_config_with_size() {
176 let icon_config = IconConfig::new().with_size(256);
177 assert_eq!(icon_config.size, Some(256));
178 assert_eq!(icon_config.get_size_or_default(), 256);
179 }
180
181 #[test]
182 #[should_panic(expected = "Icon size cannot be zero")]
183 fn test_zero_icon_size_panics() {
184 IconConfig::new().with_size(0);
185 }
186
187 #[test]
188 #[should_panic(expected = "Icon size cannot be greater than 512 pixels")]
189 fn test_large_icon_size_panics() {
190 IconConfig::new().with_size(1024);
191 }
192
193 #[test]
194 fn test_with_poll_interval() {
195 let config = FocusTrackerConfig::new().with_poll_interval(Duration::from_millis(500));
196 assert_eq!(config.poll_interval, Duration::from_millis(500));
197 }
198
199 #[test]
200 #[should_panic(expected = "Poll interval cannot be zero")]
201 fn test_zero_interval_panics() {
202 FocusTrackerConfig::new().with_poll_interval(Duration::from_millis(0));
203 }
204
205 #[test]
206 #[should_panic(expected = "Poll interval cannot be greater than 10 seconds")]
207 fn test_large_interval_panics() {
208 FocusTrackerConfig::new().with_poll_interval(Duration::from_secs(11));
209 }
210}