1#[derive(Clone, Debug, Default)]
8pub struct SelectionState {
9 selected_index: Option<usize>,
10}
11
12impl SelectionState {
13 pub fn new() -> Self {
15 Self {
16 selected_index: None,
17 }
18 }
19
20 pub fn get(&self) -> Option<usize> {
22 self.selected_index
23 }
24
25 pub fn set(&mut self, index: Option<usize>) {
27 self.selected_index = index;
28 }
29
30 pub fn clear(&mut self) {
32 self.selected_index = None;
33 }
34
35 pub fn next(&mut self, max_count: usize) {
37 if max_count == 0 {
38 return;
39 }
40 self.selected_index = Some(match self.selected_index {
41 Some(idx) => (idx + 1).min(max_count - 1),
42 None => 0,
43 });
44 }
45
46 pub fn prev(&mut self) {
48 self.selected_index = Some(match self.selected_index {
49 Some(idx) => idx.saturating_sub(1),
50 None => 0,
51 });
52 }
53
54 pub fn auto_select_first_if_empty(&mut self, has_items: bool) {
56 if self.selected_index.is_none() && has_items {
57 self.selected_index = Some(0);
58 }
59 }
60
61 pub fn jump_to_first(&mut self) {
63 self.selected_index = Some(0);
64 }
65
66 pub fn jump_to_last(&mut self, len: usize) {
68 if len > 0 {
69 self.selected_index = Some(len - 1);
70 }
71 }
72
73 pub fn is_selected(&self, index: usize) -> bool {
75 self.selected_index == Some(index)
76 }
77
78 pub fn has_selection(&self) -> bool {
80 self.selected_index.is_some()
81 }
82
83 pub fn clamp(&mut self, max_count: usize) {
85 if let Some(idx) = self.selected_index {
86 if max_count == 0 {
87 self.selected_index = None;
88 } else if idx >= max_count {
89 self.selected_index = Some(max_count - 1);
90 }
91 }
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_new_selection_is_empty() {
101 let selection = SelectionState::new();
102 assert!(selection.get().is_none());
103 assert!(!selection.has_selection());
104 }
105
106 #[test]
107 fn test_set_and_get() {
108 let mut selection = SelectionState::new();
109 selection.set(Some(5));
110 assert_eq!(selection.get(), Some(5));
111 assert!(selection.has_selection());
112 }
113
114 #[test]
115 fn test_clear() {
116 let mut selection = SelectionState::new();
117 selection.set(Some(5));
118 selection.clear();
119 assert!(selection.get().is_none());
120 }
121
122 #[test]
123 fn test_next() {
124 let mut selection = SelectionState::new();
125
126 selection.next(5);
128 assert_eq!(selection.get(), Some(0));
129
130 selection.next(5);
132 assert_eq!(selection.get(), Some(1));
133
134 selection.set(Some(4));
136 selection.next(5);
137 assert_eq!(selection.get(), Some(4));
138 }
139
140 #[test]
141 fn test_prev() {
142 let mut selection = SelectionState::new();
143
144 selection.prev();
146 assert_eq!(selection.get(), Some(0));
147
148 selection.set(Some(3));
150 selection.prev();
151 assert_eq!(selection.get(), Some(2));
152
153 selection.set(Some(0));
155 selection.prev();
156 assert_eq!(selection.get(), Some(0));
157 }
158
159 #[test]
160 fn test_auto_select_first() {
161 let mut selection = SelectionState::new();
162
163 selection.auto_select_first_if_empty(true);
165 assert_eq!(selection.get(), Some(0));
166
167 selection.set(Some(5));
169 selection.auto_select_first_if_empty(true);
170 assert_eq!(selection.get(), Some(5));
171
172 let mut selection2 = SelectionState::new();
174 selection2.auto_select_first_if_empty(false);
175 assert!(selection2.get().is_none());
176 }
177
178 #[test]
179 fn test_jump_to_first_last() {
180 let mut selection = SelectionState::new();
181
182 selection.set(Some(5));
183 selection.jump_to_first();
184 assert_eq!(selection.get(), Some(0));
185
186 selection.jump_to_last(10);
187 assert_eq!(selection.get(), Some(9));
188
189 selection.jump_to_last(0);
191 assert_eq!(selection.get(), Some(9)); }
193
194 #[test]
195 fn test_is_selected() {
196 let mut selection = SelectionState::new();
197 selection.set(Some(3));
198
199 assert!(selection.is_selected(3));
200 assert!(!selection.is_selected(0));
201 assert!(!selection.is_selected(5));
202 }
203
204 #[test]
205 fn test_clamp() {
206 let mut selection = SelectionState::new();
207 selection.set(Some(10));
208
209 selection.clamp(5);
211 assert_eq!(selection.get(), Some(4));
212
213 selection.clamp(0);
215 assert!(selection.get().is_none());
216
217 selection.set(Some(3));
219 selection.clamp(10);
220 assert_eq!(selection.get(), Some(3));
221 }
222
223 #[test]
224 fn test_next_empty_list() {
225 let mut selection = SelectionState::new();
226 selection.next(0);
227 assert!(selection.get().is_none());
228 }
229}