Skip to main content

collection_selection_confection/list/
selection.rs

1use 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    /// Converts into a cursor at the start of the selection.
16    pub fn into_cursor_at_start(self) -> CursorMut<'a, T> {
17        CursorMut::new(self.list, self.start)
18    }
19
20    /// Converts into a cursor at the end of the selection.
21    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    /// Grows the selection backward by one.
34    ///
35    /// Returns `false`, without moving, if already at the start of the list.
36    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    /// Shrinks the selection from the start by one.
45    ///
46    /// Returns `false`, without moving, if the selection is empty.
47    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    /// Shrinks the selection from the end by one.
56    ///
57    /// Returns `false`, without moving, if the selection is empty.
58    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    /// Grows the selection forward by one.
67    ///
68    /// Returns `false`, without moving, if already at the end of the list.
69    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    /// Grows the selection to the start of the list.
78    pub fn absorb_all_before(&mut self) {
79        self.start = 0;
80    }
81
82    /// Grows the selection to the end of the list.
83    pub fn absorb_all_after(&mut self) {
84        self.end = self.list.items.len();
85    }
86
87    /// Returns the first selected element.
88    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    /// Returns the last selected element.
96    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    /// Returns the element just before the selection.
118    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    /// Returns the element just after the selection.
124    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    /// Inserts an element just before the selection.
138    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    /// Inserts an element at the start of the selection.
145    pub fn insert_at_start(&mut self, value: T) {
146        self.list.items.insert(self.start, value);
147        self.end += 1;
148    }
149
150    /// Inserts an element at the end of the selection.
151    pub fn insert_at_end(&mut self, value: T) {
152        self.list.items.insert(self.end, value);
153        self.end += 1;
154    }
155
156    /// Inserts an element just after the selection.
157    pub fn insert_after_end(&mut self, value: T) {
158        self.list.items.insert(self.end, value);
159    }
160
161    /// Removes and returns the element just before the selection.
162    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    /// Removes and returns the first selected element.
172    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    /// Removes and returns the last selected element.
181    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    /// Removes and returns the element just after the selection.
190    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    /// Removes and returns the selected elements, leaving the selection empty.
198    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    /// Replaces the selected elements with `other`.
205    ///
206    /// Afterwards, the selection covers exactly the elements from `other`.
207    ///
208    /// Returns the previously selected elements.
209    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    /// Iterates over the selected elements.
221    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}