linked_vector/
cursor.rs

1
2use core::ops::Deref;
3use core::ops::DerefMut;
4
5use crate::linked_vector::*;
6
7/// A cursor is a position within a linked vector. It can be used to traverse
8/// the list in either direction, and to access the element at the current
9/// position.
10/// 
11pub trait CursorBase<T> {
12    /// Returns a reference to the element at the cursor's current position. If
13    /// the feature, `"optionless-accessors"`, is disabled, the return type is
14    /// `Option<&T>` instead of `&T`. This feature is disabled by default.
15    /// 
16    #[cfg(feature = "optionless-accessors")]
17    fn get(&self) -> &T;
18
19    /// Returns a reference to the element at the cursor's current position,
20    /// or `None` if the underlying vector is empty. Enable the 
21    /// `"optionless-accessors"` feature to remove the `Option` from the return 
22    /// type, see [usage notes](./index.html#usage).
23    /// 
24    #[cfg(not(feature = "optionless-accessors"))]
25    fn get(&self) -> Option<&T>;
26
27    /// Returns the handle of the element at the cursor's current position.
28    /// 
29    fn node(&self) -> HNode;
30
31    /// Moves the cursor to the specified handle. The handle must be valid. If
32    /// the feature, `"optionless-accessors"`, is disabled, the return type is
33    /// `bool`. This feature is disabled by default, see 
34    /// [usage notes](./index.html#usage).
35    /// 
36    #[cfg(feature = "optionless-accessors")]
37    fn move_to(&mut self, handle: HNode);
38
39    /// Moves the cursor to the specified handle. The handle must be valid. 
40    /// Returns true if the move was successful. If the `"optionless-accessors"`
41    /// feature is enabled, this method doesn't return a value. This feature is
42    /// disabled by default, see [usage notes](./index.html#usage).
43    /// 
44    #[cfg(not(feature = "optionless-accessors"))]
45    fn move_to(&mut self, handle: HNode) -> bool;
46
47    /// Moves the cursor to the next element. Returns the handle of the next
48    /// element if the cursor was moved, None if the cursor was already at the
49    /// end of the list.
50    /// 
51    fn move_next(&mut self) -> Option<HNode>;
52
53    /// Moves the cursor to the previous element. Returns the handle of the
54    /// previous element if the cursor was moved, None if the cursor was
55    /// already at the start of the list.
56    /// 
57    fn move_prev(&mut self) -> Option<HNode>;
58
59    /// Moves the cursor to the end of the list. Returns the handle of the
60    /// last element if the cursor was moved, None if the list is empty.
61    /// 
62    fn move_to_back(&mut self) -> Option<HNode>;
63
64    /// Moves the cursor to the start of the list. Returns the handle of the
65    /// first element if the cursor was moved, None if the list is empty.
66    /// 
67    fn move_to_front(&mut self) -> Option<HNode>;
68
69    /// Moves the cursor to the start of the list. Returns the handle of the
70    /// first element if the cursor was moved, None if the list is empty.
71    /// 
72    #[deprecated(since = "1.1.0", note = "Use move_to_front() instead.")]
73    fn move_to_start(&mut self) -> Option<HNode>;
74
75    /// Moves the cursor to the end of the list. Returns the handle of the
76    /// last element if the cursor was moved, None if the list is empty.
77    /// 
78    #[deprecated(since = "1.1.0", note = "Use move_to_back() instead.")]
79    fn move_to_end(&mut self) -> Option<HNode>;
80
81    /// Moves the cursor forward by the specified number of elements. Returns
82    /// the handle of the element at the new position if the cursor was moved,
83    /// Err(handle) if the cursor did not move forward by the specified amount.
84    /// The handle at the current position after the move is returned in 
85    /// either Result variant.
86    /// 
87    fn forward(&mut self, n: usize) -> Result<HNode, HNode>;
88
89    /// Moves the cursor backward by the specified number of elements. Returns
90    /// the handle of the element at the new position if the cursor was moved,
91    /// Err(handle) if the cursor did not move backward by the specified amount.
92    /// The handle at the current position after the move is returned in 
93    /// either Result variant.
94    /// 
95    fn backward(&mut self, n: usize) -> Result<HNode, HNode>;
96}
97
98/// A cursor which can only read the elements of the list.
99/// 
100pub struct Cursor<'a, T> {
101    lvec   : &'a LinkedVector<T>,
102    handle : HNode,
103}
104
105impl<'a, T> Cursor<'a, T> {
106    pub(crate) fn new(lvec   : &'a LinkedVector<T>, 
107                      handle : HNode) 
108        -> Self 
109    {
110        #[cfg(debug_assertions)]
111        lvec.check_handle(handle);
112
113        Self {
114            lvec,
115            handle,
116        }
117    }
118}
119impl<'a, T> CursorBase<T> for Cursor<'a, T> {
120    #[cfg(feature = "optionless-accessors")]
121    fn get(&self) -> &T {
122        self.lvec.get(self.handle)
123    }
124
125    #[cfg(not(feature = "optionless-accessors"))]
126    fn get(&self) -> Option<&T> {
127        if self.lvec.is_empty() {
128            None
129        } else {
130            self.lvec.get(self.handle)
131        }
132    }
133
134    fn node(&self) -> HNode {
135        self.handle
136    }
137
138    #[cfg(feature = "optionless-accessors")]
139    fn move_to(&mut self, handle: HNode) {
140        #[cfg(debug_assertions)]
141        self.lvec.check_handle(handle);
142
143        self.handle = handle;
144    }
145
146    #[cfg(not(feature = "optionless-accessors"))]
147    fn move_to(&mut self, handle: HNode) -> bool {
148        #[cfg(debug_assertions)]
149        self.lvec.check_handle(handle);
150        
151        if self.lvec.is_empty() {
152            false
153        } else {
154            self.handle = handle;
155            true
156        }
157    }
158
159    fn move_next(&mut self) -> Option<HNode> {
160        self.lvec.next_node(self.handle).map(|hnext| {
161            self.handle = hnext;
162            hnext
163        })
164    }
165
166    fn move_prev(&mut self) -> Option<HNode> {
167        self.lvec.prev_node(self.handle).map(|hprev| {
168            self.handle = hprev;
169            hprev
170        })
171    }
172
173    fn move_to_front(&mut self) -> Option<HNode> {
174        self.lvec.front_node().map(|hstart| {
175            self.handle = hstart;
176            hstart
177        })
178    }
179
180    fn move_to_back(&mut self) -> Option<HNode> {
181        self.lvec.back_node().map(|hend| {
182            self.handle = hend;
183            hend
184        })
185    }
186
187    fn move_to_start(&mut self) -> Option<HNode> {
188        self.move_to_front()
189    }
190
191    fn move_to_end(&mut self) -> Option<HNode> {
192        self.move_to_back()
193    }
194    fn forward(&mut self, n: usize) ->Result<HNode, HNode> {
195        for _ in 0..n {
196            if self.move_next().is_none() {
197                return Err(self.handle);
198            }
199        }
200        Ok(self.handle)
201    }
202    fn backward(&mut self, n: usize) -> Result<HNode, HNode> {
203        for _ in 0..n {
204            if self.move_prev().is_none() {
205                return Err(self.handle);
206            }
207        }
208        Ok(self.handle)
209    }
210}
211
212impl<'a, T> Deref for Cursor<'a, T> {
213    type Target = T;
214
215    fn deref(&self) -> &Self::Target {
216        #[cfg(feature = "optionless-accessors")]
217        { self.get() }
218
219        #[cfg(not(feature = "optionless-accessors"))]
220        { self.get().unwrap() }
221    }
222}
223
224/// A cursor which can read and write the elements of the list.
225/// 
226pub struct CursorMut<'a, T> {
227    lvec   : &'a mut LinkedVector<T>,
228    handle : HNode,
229}
230
231impl<'a, T> CursorMut<'a, T> {
232
233    pub(crate) fn new(lvec   : &'a mut LinkedVector<T>, 
234                      handle : HNode) 
235        -> Self 
236    {
237        #[cfg(debug_assertions)]
238        lvec.check_handle(handle);
239
240        Self {
241            lvec,
242            handle,
243        }
244    }
245
246    /// Returns `true` if the vector the cursor is attached to is empty. Since
247    /// a mutable cursor can remove items, this is provided as a means to avoid 
248    /// panics if the cursor is being used to remove items. If the underlying 
249    /// vector is empty, other operations may panic.
250    /// 
251    pub fn is_empty(&self) -> bool {
252        self.lvec.is_empty()
253    }
254
255    /// Returns a mutable reference to the element at the cursor's current
256    /// position. If the `optionless-accessors` feature is disabled, this will
257    /// return an `Option` holding the reference, or `None`. This feature is
258    /// disabled by default, see [usage notes](./index.html#usage).
259    /// 
260    #[cfg(feature = "optionless-accessors")]
261    pub fn get_mut(&mut self) -> &mut T {
262        self.lvec.get_mut(self.handle)
263    }
264
265    /// Returns a mutable reference to the element at the cursor's current
266    /// position, or `None` if the underlying vector is empty. If the 
267    /// `optionless-accessors` feature is enabled, this will return a reference
268    /// directly. This feature is disabled by default, see 
269    /// [usage notes](./index.html#usage).
270    /// 
271    #[cfg(not(feature = "optionless-accessors"))]
272    pub fn get_mut(&mut self) -> Option<&mut T> {
273        if self.lvec.is_empty() {
274            None
275        } else {
276            self.lvec.get_mut(self.handle)
277        }
278    }
279
280    /// Inserts a new element at the cursor's current position. The cursor
281    /// will be moved to the new element. Returns the handle of the new
282    /// element.
283    /// 
284    pub fn insert(&mut self, value: T) -> HNode {
285        self.handle = self.lvec.insert(self.handle, value);
286        self.handle
287    }
288
289    /// Inserts a new element after the cursor's current position. The cursor
290    /// will still be at the same position. Returns the handle of the new
291    /// element.
292    /// 
293    pub fn insert_after(&mut self, value: T) -> HNode {
294        self.lvec.insert_after(self.handle, value)
295    }
296
297    /// Removes the element at the current position and returns its value. The 
298    /// cursor will be moved to the next element if not at the end of the 
299    /// vector, otherwise it moves to the new end. If the vector is already 
300    /// empty, `None` is returned. The `"cursor-remove"` feature must be
301    /// enabled to use this method, see [usage notes](./index.html#usage).
302    /// 
303    #[cfg(feature = "cursor-remove")]
304    pub fn remove(&mut self) -> Option<T> {
305        if self.lvec.is_empty() {
306            None
307        } else {
308            let hrem = self.handle;
309            if let Some(hnext) = self.lvec.next_node(self.handle) {
310                self.handle = hnext;
311            } else if let Some(hprev) = self.lvec.prev_node(self.handle) {
312                self.handle = hprev;
313            } else {
314                self.handle = BAD_HANDLE;
315            }
316            #[cfg(not(feature = "optionless-accessors"))]
317            { self.lvec.remove(hrem) }
318
319            #[cfg(feature = "optionless-accessors")]
320            { Some(self.lvec.remove(hrem)) }
321        }
322    }
323}
324
325impl<'a, T> CursorBase<T> for CursorMut<'a, T> {
326    #[cfg(feature = "optionless-accessors")]
327    fn get(&self) -> &T {
328        self.lvec.get(self.handle)
329    }
330
331    #[cfg(not(feature = "optionless-accessors"))]
332    fn get(&self) -> Option<&T> {
333        if self.lvec.is_empty() {
334            None
335        } else {
336            self.lvec.get(self.handle)
337        }
338    }
339
340    fn node(&self) -> HNode {
341        self.handle
342    }
343
344    #[cfg(feature = "optionless-accessors")]
345    fn move_to(&mut self, handle: HNode) {
346        #[cfg(debug_assertions)]
347        self.lvec.check_handle(handle);
348        
349        self.handle = handle;
350    }
351
352    #[cfg(not(feature = "optionless-accessors"))]
353    fn move_to(&mut self, handle: HNode) -> bool {
354        #[cfg(debug_assertions)]
355        self.lvec.check_handle(handle);
356        
357        if self.lvec.is_empty() {
358            false
359        } else {
360            self.handle = handle;
361            true
362        }
363    }
364
365    fn move_next(&mut self) -> Option<HNode> {
366        self.lvec.next_node(self.handle).map(|hnext| {
367            self.handle = hnext;
368            hnext
369        })
370    }
371
372    fn move_prev(&mut self) -> Option<HNode> {
373        self.lvec.prev_node(self.handle).map(|hprev| {
374            self.handle = hprev;
375            hprev
376        })
377    }
378
379    fn move_to_front(&mut self) -> Option<HNode> {
380        self.lvec.front_node().map(|hstart| {
381            self.handle = hstart;
382            hstart
383        })
384    }
385
386    fn move_to_back(&mut self) -> Option<HNode> {
387        self.lvec.back_node().map(|hend| {
388            self.handle = hend;
389            hend
390        })
391    }
392
393    fn move_to_start(&mut self) -> Option<HNode> {
394        self.move_to_front()
395    }
396
397    fn move_to_end(&mut self) -> Option<HNode> {
398        self.move_to_back()
399    }
400
401    fn forward(&mut self, n: usize) -> Result<HNode, HNode> {
402        for _ in 0..n {
403            if self.move_next().is_none() {
404                return Err(self.handle);
405            }
406        }
407        Ok(self.handle)
408    }
409
410    fn backward(&mut self, n: usize) -> Result<HNode, HNode> {
411        for _ in 0..n {
412            if self.move_prev().is_none() {
413                return Err(self.handle);
414            }
415        }
416        Ok(self.handle)
417    }
418}
419
420impl<'a, T> Deref for CursorMut<'a, T> {
421    type Target = T;
422
423    fn deref(&self) -> &Self::Target {
424        #[cfg(feature = "optionless-accessors")]
425        { self.get() }
426
427        #[cfg(not(feature = "optionless-accessors"))]
428        { self.get().unwrap() }
429    }
430}
431
432impl<'a, T> DerefMut for CursorMut<'a, T> {
433    fn deref_mut(&mut self) -> &mut Self::Target {
434        #[cfg(feature = "optionless-accessors")]
435        { self.get_mut() }
436
437        #[cfg(not(feature = "optionless-accessors"))]
438        { self.get_mut().unwrap() }
439    }
440}