collection_selection_confection/list/
cursor.rs1use super::LinkedList;
2use super::selection::SelectionMut;
3
4pub struct CursorMut<'a, T> {
6 list: &'a mut LinkedList<T>,
7 index: usize,
8}
9
10impl<'a, T> CursorMut<'a, T> {
11 pub(super) fn new(list: &'a mut LinkedList<T>, index: usize) -> Self {
12 Self { list, index }
13 }
14
15 pub fn into_selection(self) -> SelectionMut<'a, T> {
17 SelectionMut::new(self.list, self.index, self.index)
18 }
19
20 pub fn move_prev(&mut self) -> bool {
24 if self.index == 0 {
25 return false;
26 }
27 self.index -= 1;
28 true
29 }
30
31 pub fn move_next(&mut self) -> bool {
35 if self.index == self.list.items.len() {
36 return false;
37 }
38 self.index += 1;
39 true
40 }
41
42 pub fn peek_before(&self) -> Option<&T> {
44 let i = self.index.checked_sub(1)?;
45 self.list.items.get(i)
46 }
47
48 pub fn peek_after(&self) -> Option<&T> {
50 self.list.items.get(self.index)
51 }
52
53 pub fn peek_before_mut(&mut self) -> Option<&mut T> {
54 let i = self.index.checked_sub(1)?;
55 self.list.items.get_mut(i)
56 }
57
58 pub fn peek_after_mut(&mut self) -> Option<&mut T> {
59 self.list.items.get_mut(self.index)
60 }
61
62 pub fn insert_before(&mut self, value: T) {
64 self.list.items.insert(self.index, value);
65 self.index += 1;
66 }
67
68 pub fn insert_after(&mut self, value: T) {
70 self.list.items.insert(self.index, value);
71 }
72
73 pub fn remove_before(&mut self) -> Option<T> {
75 if self.index == 0 {
76 return None;
77 }
78 self.index -= 1;
79 Some(self.list.items.remove(self.index))
80 }
81
82 pub fn remove_after(&mut self) -> Option<T> {
84 if self.index == self.list.items.len() {
85 return None;
86 }
87 Some(self.list.items.remove(self.index))
88 }
89
90 pub fn splice_before(&mut self, other: LinkedList<T>) {
92 let len = other.items.len();
93 self.list.items.splice(self.index..self.index, other.items);
94 self.index += len;
95 }
96
97 pub fn splice_after(&mut self, other: LinkedList<T>) {
99 self.list.items.splice(self.index..self.index, other.items);
100 }
101
102 pub fn split_before(&mut self) -> LinkedList<T> {
104 let after = self.list.items.split_off(self.index);
105 let before = std::mem::replace(&mut self.list.items, after);
106 self.index = 0;
107 LinkedList { items: before }
108 }
109
110 pub fn split_after(&mut self) -> LinkedList<T> {
112 LinkedList {
113 items: self.list.items.split_off(self.index),
114 }
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121 use crate::list::tests::list_of;
122
123 #[test]
124 fn insert_before_into_empty() {
125 let mut list = LinkedList::new();
126 list.cursor_mut_at_start().insert_before(1);
127 assert_eq!(list.items, [1]);
128 }
129
130 #[test]
131 fn insert_before_twice_keeps_order() {
132 let mut list = LinkedList::new();
133 let mut cursor = list.cursor_mut_at_start();
134 cursor.insert_before(1);
135 cursor.insert_before(2);
136 assert_eq!(list.items, [1, 2]);
137 }
138
139 #[test]
140 fn insert_after_twice_keeps_order() {
141 let mut list = LinkedList::new();
142 let mut cursor = list.cursor_mut_at_start();
143 cursor.insert_after(2);
144 cursor.insert_after(1);
145 assert_eq!(cursor.peek_before(), None);
146 assert_eq!(cursor.peek_after(), Some(&1));
147 assert_eq!(list.items, [1, 2]);
148 }
149
150 #[test]
151 fn peek_around_cursor() {
152 let mut list = LinkedList::new();
153 list.cursor_mut_at_start().insert_before(1);
154 let mut cursor = list.cursor_mut_at_start();
155 assert_eq!(cursor.peek_before(), None);
156 assert_eq!(cursor.peek_after(), Some(&1));
157 cursor.insert_before(0);
158 assert_eq!(cursor.peek_before(), Some(&0));
159 assert_eq!(cursor.peek_after(), Some(&1));
160 }
161
162 #[test]
163 fn peek_mut_modifies_values() {
164 let mut list = LinkedList::new();
165 list.cursor_mut_at_start().insert_before(1);
166 let mut cursor = list.cursor_mut_at_start();
167 cursor.insert_before(0);
168 *cursor.peek_before_mut().unwrap() += 10;
169 *cursor.peek_after_mut().unwrap() += 20;
170 assert_eq!(list.items, [10, 21]);
171 }
172
173 #[test]
174 fn split_before_takes_elements_before_cursor() {
175 let mut list = LinkedList::new();
176 list.cursor_mut_at_start().insert_before(2);
177 let mut cursor = list.cursor_mut_at_start();
178 cursor.insert_before(0);
179 cursor.insert_before(1);
180 let before = cursor.split_before();
181 assert_eq!(cursor.peek_before(), None);
182 assert_eq!(cursor.peek_after(), Some(&2));
183 assert_eq!(before.items, [0, 1]);
184 assert_eq!(list.items, [2]);
185 }
186
187 #[test]
188 fn split_after_takes_elements_after_cursor() {
189 let mut list = LinkedList::new();
190 list.cursor_mut_at_start().insert_before(2);
191 let mut cursor = list.cursor_mut_at_start();
192 cursor.insert_before(0);
193 cursor.insert_before(1);
194 let after = cursor.split_after();
195 assert_eq!(cursor.peek_before(), Some(&1));
196 assert_eq!(cursor.peek_after(), None);
197 assert_eq!(after.items, [2]);
198 assert_eq!(list.items, [0, 1]);
199 }
200
201 #[test]
202 fn cursor_at_end_peeks_last() {
203 let mut list = list_of(&[0, 1]);
204 let cursor = list.cursor_mut_at_end();
205 assert_eq!(cursor.peek_before(), Some(&1));
206 assert_eq!(cursor.peek_after(), None);
207 }
208
209 #[test]
210 fn move_stops_at_ends() {
211 let mut list = list_of(&[0, 1]);
212 let mut cursor = list.cursor_mut_at_start();
213 assert!(!cursor.move_prev());
214 assert!(cursor.move_next());
215 assert_eq!(cursor.peek_before(), Some(&0));
216 assert_eq!(cursor.peek_after(), Some(&1));
217 assert!(cursor.move_next());
218 assert!(!cursor.move_next());
219 assert_eq!(cursor.peek_before(), Some(&1));
220 assert!(cursor.move_prev());
221 assert_eq!(cursor.peek_after(), Some(&1));
222 }
223
224 #[test]
225 fn remove_on_each_side() {
226 let mut list = list_of(&[0, 1, 2]);
227 let mut cursor = list.cursor_mut_at_start();
228 cursor.move_next();
229 assert_eq!(cursor.remove_before(), Some(0));
230 assert_eq!(cursor.remove_before(), None);
231 assert_eq!(cursor.remove_after(), Some(1));
232 assert_eq!(cursor.peek_after(), Some(&2));
233 assert_eq!(cursor.remove_after(), Some(2));
234 assert_eq!(cursor.remove_after(), None);
235 assert!(list.is_empty());
236 }
237
238 #[test]
239 fn splice_before_puts_cursor_after_spliced() {
240 let mut list = list_of(&[0, 3]);
241 let mut cursor = list.cursor_mut_at_start();
242 cursor.move_next();
243 cursor.splice_before(list_of(&[1, 2]));
244 assert_eq!(cursor.peek_before(), Some(&2));
245 assert_eq!(cursor.peek_after(), Some(&3));
246 assert_eq!(list.items, [0, 1, 2, 3]);
247 }
248
249 #[test]
250 fn splice_after_keeps_cursor_before_spliced() {
251 let mut list = list_of(&[0, 3]);
252 let mut cursor = list.cursor_mut_at_start();
253 cursor.move_next();
254 cursor.splice_after(list_of(&[1, 2]));
255 assert_eq!(cursor.peek_before(), Some(&0));
256 assert_eq!(cursor.peek_after(), Some(&1));
257 assert_eq!(list.items, [0, 1, 2, 3]);
258 }
259}