collection_selection_confection/list/
selection.rs1use super::LinkedList;
2use super::cursor::CursorMut;
3
4pub struct SelectionMut<'a, T> {
5 list: &'a mut LinkedList<T>,
6 start: usize,
7 end: usize,
8}
9
10impl<'a, T> SelectionMut<'a, T> {
11 pub(super) fn new(list: &'a mut LinkedList<T>, start: usize, end: usize) -> Self {
12 Self { list, start, end }
13 }
14
15 pub fn into_cursor_at_start(self) -> CursorMut<'a, T> {
17 CursorMut::new(self.list, self.start)
18 }
19
20 pub fn into_cursor_at_end(self) -> CursorMut<'a, T> {
22 CursorMut::new(self.list, self.end)
23 }
24
25 pub fn len(&self) -> usize {
26 self.end - self.start
27 }
28
29 pub fn is_empty(&self) -> bool {
30 self.start == self.end
31 }
32
33 pub fn move_start_prev(&mut self) -> bool {
37 if self.start == 0 {
38 return false;
39 }
40 self.start -= 1;
41 true
42 }
43
44 pub fn move_start_next(&mut self) -> bool {
48 if self.start == self.end {
49 return false;
50 }
51 self.start += 1;
52 true
53 }
54
55 pub fn move_end_prev(&mut self) -> bool {
59 if self.end == self.start {
60 return false;
61 }
62 self.end -= 1;
63 true
64 }
65
66 pub fn move_end_next(&mut self) -> bool {
70 if self.end == self.list.items.len() {
71 return false;
72 }
73 self.end += 1;
74 true
75 }
76
77 pub fn absorb_all_before(&mut self) {
79 self.start = 0;
80 }
81
82 pub fn absorb_all_after(&mut self) {
84 self.end = self.list.items.len();
85 }
86
87 pub fn first(&self) -> Option<&T> {
89 if self.is_empty() {
90 return None;
91 }
92 self.list.items.get(self.start)
93 }
94
95 pub fn last(&self) -> Option<&T> {
97 if self.is_empty() {
98 return None;
99 }
100 self.list.items.get(self.end - 1)
101 }
102
103 pub fn first_mut(&mut self) -> Option<&mut T> {
104 if self.is_empty() {
105 return None;
106 }
107 self.list.items.get_mut(self.start)
108 }
109
110 pub fn last_mut(&mut self) -> Option<&mut T> {
111 if self.is_empty() {
112 return None;
113 }
114 self.list.items.get_mut(self.end - 1)
115 }
116
117 pub fn peek_before_start(&self) -> Option<&T> {
119 let i = self.start.checked_sub(1)?;
120 self.list.items.get(i)
121 }
122
123 pub fn peek_after_end(&self) -> Option<&T> {
125 self.list.items.get(self.end)
126 }
127
128 pub fn peek_before_start_mut(&mut self) -> Option<&mut T> {
129 let i = self.start.checked_sub(1)?;
130 self.list.items.get_mut(i)
131 }
132
133 pub fn peek_after_end_mut(&mut self) -> Option<&mut T> {
134 self.list.items.get_mut(self.end)
135 }
136
137 pub fn insert_before_start(&mut self, value: T) {
139 self.list.items.insert(self.start, value);
140 self.start += 1;
141 self.end += 1;
142 }
143
144 pub fn insert_at_start(&mut self, value: T) {
146 self.list.items.insert(self.start, value);
147 self.end += 1;
148 }
149
150 pub fn insert_at_end(&mut self, value: T) {
152 self.list.items.insert(self.end, value);
153 self.end += 1;
154 }
155
156 pub fn insert_after_end(&mut self, value: T) {
158 self.list.items.insert(self.end, value);
159 }
160
161 pub fn remove_before_start(&mut self) -> Option<T> {
163 if self.start == 0 {
164 return None;
165 }
166 self.start -= 1;
167 self.end -= 1;
168 Some(self.list.items.remove(self.start))
169 }
170
171 pub fn remove_first(&mut self) -> Option<T> {
173 if self.is_empty() {
174 return None;
175 }
176 self.end -= 1;
177 Some(self.list.items.remove(self.start))
178 }
179
180 pub fn remove_last(&mut self) -> Option<T> {
182 if self.is_empty() {
183 return None;
184 }
185 self.end -= 1;
186 Some(self.list.items.remove(self.end))
187 }
188
189 pub fn remove_after_end(&mut self) -> Option<T> {
191 if self.end == self.list.items.len() {
192 return None;
193 }
194 Some(self.list.items.remove(self.end))
195 }
196
197 pub fn take(&mut self) -> LinkedList<T> {
199 let items = self.list.items.drain(self.start..self.end).collect();
200 self.end = self.start;
201 LinkedList { items }
202 }
203
204 pub fn replace(&mut self, other: LinkedList<T>) -> LinkedList<T> {
210 let len = other.items.len();
211 let items = self
212 .list
213 .items
214 .splice(self.start..self.end, other.items)
215 .collect();
216 self.end = self.start + len;
217 LinkedList { items }
218 }
219
220 pub fn iter(&self) -> impl DoubleEndedIterator<Item = &T> + ExactSizeIterator {
222 self.list.items[self.start..self.end].iter()
223 }
224
225 pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut T> + ExactSizeIterator {
226 self.list.items[self.start..self.end].iter_mut()
227 }
228}
229
230#[cfg(test)]
231mod tests {
232 use crate::list::tests::list_of;
233
234 #[test]
235 fn cursor_round_trip() {
236 let mut list = list_of(&[0, 1]);
237 let mut cursor = list.cursor_mut_at_start();
238 cursor.move_next();
239 let selection = cursor.into_selection();
240 assert!(selection.is_empty());
241 assert_eq!(selection.peek_before_start(), Some(&0));
242 assert_eq!(selection.peek_after_end(), Some(&1));
243 let cursor = selection.into_cursor_at_end();
244 assert_eq!(cursor.peek_before(), Some(&0));
245 assert_eq!(cursor.peek_after(), Some(&1));
246 }
247
248 #[test]
249 fn into_cursor_at_each_end() {
250 let mut list = list_of(&[0, 1, 2]);
251 let mut selection = list.cursor_mut_at_start().into_selection();
252 selection.move_end_next();
253 selection.move_end_next();
254 let cursor = selection.into_cursor_at_end();
255 assert_eq!(cursor.peek_before(), Some(&1));
256 let mut selection = cursor.into_selection();
257 selection.move_start_prev();
258 let cursor = selection.into_cursor_at_start();
259 assert_eq!(cursor.peek_before(), Some(&0));
260 assert_eq!(cursor.peek_after(), Some(&1));
261 }
262
263 #[test]
264 fn boundaries_stop_at_each_other_and_ends() {
265 let mut list = list_of(&[0, 1]);
266 let mut selection = list.cursor_mut_at_start().into_selection();
267 assert!(!selection.move_start_prev());
268 assert!(!selection.move_start_next());
269 assert!(!selection.move_end_prev());
270 assert!(selection.move_end_next());
271 assert!(selection.move_end_next());
272 assert!(!selection.move_end_next());
273 assert_eq!(selection.len(), 2);
274 assert!(selection.move_start_next());
275 assert!(selection.move_start_next());
276 assert!(!selection.move_start_next());
277 assert!(selection.is_empty());
278 }
279
280 #[test]
281 fn absorb_all_on_each_side() {
282 let mut list = list_of(&[0, 1, 2, 3]);
283 let mut selection = list.cursor_mut_at_start().into_selection();
284 selection.move_end_next();
285 selection.move_end_next();
286 selection.move_start_next();
287 selection.absorb_all_before();
288 assert_eq!(selection.iter().copied().collect::<Vec<_>>(), [0, 1]);
289 selection.absorb_all_after();
290 assert_eq!(selection.iter().copied().collect::<Vec<_>>(), [0, 1, 2, 3]);
291 assert_eq!(selection.peek_before_start(), None);
292 assert_eq!(selection.peek_after_end(), None);
293 }
294
295 #[test]
296 fn first_and_last_inside_selection() {
297 let mut list = list_of(&[0, 1, 2, 3]);
298 let mut selection = list.cursor_mut_at_start().into_selection();
299 assert_eq!(selection.first(), None);
300 assert_eq!(selection.last(), None);
301 selection.move_end_next();
302 selection.move_end_next();
303 selection.move_end_next();
304 selection.move_start_next();
305 assert_eq!(selection.first(), Some(&1));
306 assert_eq!(selection.last(), Some(&2));
307 *selection.first_mut().unwrap() += 10;
308 *selection.last_mut().unwrap() += 20;
309 assert_eq!(list.items, [0, 11, 22, 3]);
310 }
311
312 #[test]
313 fn peek_mut_outside_selection() {
314 let mut list = list_of(&[0, 1, 2]);
315 let mut selection = list.cursor_mut_at_start().into_selection();
316 selection.move_end_next();
317 selection.move_end_next();
318 selection.move_start_next();
319 *selection.peek_before_start_mut().unwrap() += 10;
320 *selection.peek_after_end_mut().unwrap() += 20;
321 assert_eq!(list.items, [10, 1, 22]);
322 }
323
324 #[test]
325 fn insert_outside_selection() {
326 let mut list = list_of(&[1]);
327 let mut selection = list.cursor_mut_at_start().into_selection();
328 selection.move_end_next();
329 selection.insert_before_start(0);
330 selection.insert_after_end(2);
331 assert_eq!(selection.iter().copied().collect::<Vec<_>>(), [1]);
332 assert_eq!(list.items, [0, 1, 2]);
333 }
334
335 #[test]
336 fn insert_inside_selection() {
337 let mut list = list_of(&[0, 2, 4]);
338 let mut selection = list.cursor_mut_at_start().into_selection();
339 selection.move_end_next();
340 selection.move_end_next();
341 selection.move_start_next();
342 selection.insert_at_start(1);
343 selection.insert_at_end(3);
344 assert_eq!(selection.iter().copied().collect::<Vec<_>>(), [1, 2, 3]);
345 assert_eq!(selection.peek_before_start(), Some(&0));
346 assert_eq!(selection.peek_after_end(), Some(&4));
347 assert_eq!(list.items, [0, 1, 2, 3, 4]);
348 }
349
350 #[test]
351 fn insert_inside_empty_selection() {
352 let mut list = list_of(&[0, 3]);
353 let mut selection = list.cursor_mut_at_start().into_selection();
354 selection.move_end_next();
355 selection.move_start_next();
356 selection.insert_at_start(2);
357 selection.insert_at_start(1);
358 assert_eq!(selection.len(), 2);
359 assert_eq!(selection.first(), Some(&1));
360 assert_eq!(selection.last(), Some(&2));
361 assert_eq!(list.items, [0, 1, 2, 3]);
362 }
363
364 #[test]
365 fn remove_outside_selection() {
366 let mut list = list_of(&[0, 1, 2]);
367 let mut selection = list.cursor_mut_at_start().into_selection();
368 selection.move_end_next();
369 selection.move_end_next();
370 selection.move_start_next();
371 assert_eq!(selection.remove_before_start(), Some(0));
372 assert_eq!(selection.remove_after_end(), Some(2));
373 assert_eq!(selection.remove_before_start(), None);
374 assert_eq!(selection.remove_after_end(), None);
375 assert_eq!(selection.iter().copied().collect::<Vec<_>>(), [1]);
376 assert_eq!(list.items, [1]);
377 }
378
379 #[test]
380 fn remove_inside_selection() {
381 let mut list = list_of(&[0, 1, 2, 3, 4]);
382 let mut selection = list.cursor_mut_at_start().into_selection();
383 selection.move_end_next();
384 selection.move_end_next();
385 selection.move_end_next();
386 selection.move_end_next();
387 selection.move_start_next();
388 assert_eq!(selection.remove_first(), Some(1));
389 assert_eq!(selection.remove_last(), Some(3));
390 assert_eq!(selection.iter().copied().collect::<Vec<_>>(), [2]);
391 assert_eq!(selection.peek_before_start(), Some(&0));
392 assert_eq!(selection.peek_after_end(), Some(&4));
393 assert_eq!(selection.remove_last(), Some(2));
394 assert_eq!(selection.remove_first(), None);
395 assert_eq!(selection.remove_last(), None);
396 assert_eq!(list.items, [0, 4]);
397 }
398
399 #[test]
400 fn take_empties_selection() {
401 let mut list = list_of(&[0, 1, 2, 3]);
402 let mut selection = list.cursor_mut_at_start().into_selection();
403 selection.move_end_next();
404 selection.move_end_next();
405 selection.move_end_next();
406 selection.move_start_next();
407 let taken = selection.take();
408 assert!(selection.is_empty());
409 assert_eq!(selection.peek_before_start(), Some(&0));
410 assert_eq!(selection.peek_after_end(), Some(&3));
411 assert_eq!(taken.items, [1, 2]);
412 assert_eq!(list.items, [0, 3]);
413 }
414
415 #[test]
416 fn replace_selects_new_contents() {
417 let mut list = list_of(&[0, 1, 2]);
418 let mut selection = list.cursor_mut_at_start().into_selection();
419 selection.move_end_next();
420 selection.move_end_next();
421 selection.move_start_next();
422 let old = selection.replace(list_of(&[10, 11, 12]));
423 assert_eq!(selection.iter().copied().collect::<Vec<_>>(), [10, 11, 12]);
424 assert_eq!(selection.peek_after_end(), Some(&2));
425 assert_eq!(old.items, [1]);
426 assert_eq!(list.items, [0, 10, 11, 12, 2]);
427 }
428
429 #[test]
430 fn iter_mut_within_selection() {
431 let mut list = list_of(&[0, 1, 2]);
432 let mut selection = list.cursor_mut_at_start().into_selection();
433 selection.move_end_next();
434 selection.move_end_next();
435 selection.move_start_next();
436 for value in selection.iter_mut() {
437 *value *= 10;
438 }
439 assert_eq!(selection.iter().rev().copied().collect::<Vec<_>>(), [10]);
440 assert_eq!(list.items, [0, 10, 2]);
441 }
442}