pub struct CursorMut<'a, T> { /* private fields */ }Expand description
A cursor with mutable access to a PieList.
A CursorMut provides a flexible way to inspect and modify a PieList
at a specific location. It holds a mutable reference to its PieList,
which means that while the cursor exists, the list cannot be modified by
any other means.
The cursor has two special states:
- “Before Start”: Positioned before the first element (
index()returnsNone). - “After End”: Positioned after the last element (
index()returnsNone).
§Rationale
The cursor pattern is essential for implementing complex list operations
efficiently, such as split_before or splice_before. It avoids the need
for repeated index-based lookups from the beginning or end of the list.
§Example
use pie_core::{ElemPool, PieList};
let mut pool = ElemPool::new();
let mut list = PieList::new(&mut pool);
list.push_back(10, &mut pool).unwrap();
list.push_back(20, &mut pool).unwrap();
let mut cursor = list.cursor_mut(&mut pool); // Starts at index 0 (10)
// Move forward
cursor.move_next(&pool);
if let Some(val) = cursor.peek_mut(&mut pool) {
*val = 99;
}
assert_eq!(cursor.peek(&pool), Some(&99));
// Move backward (supports wrapping from End to Tail, etc)
cursor.move_next(&pool); // Now After End
cursor.move_prev(&pool); // Back to Tail (99)
assert_eq!(cursor.peek(&pool), Some(&99));
list.clear(&mut pool);Implementations§
Source§impl<'a, T> CursorMut<'a, T>
impl<'a, T> CursorMut<'a, T>
Sourcepub fn index(&self) -> Option<usize>
pub fn index(&self) -> Option<usize>
Returns the logical index of the cursor’s current position.
The index is 0-based. If the cursor is pointing “Before Start” or “After End”,
this method returns None.
§Example
let mut cursor = list.cursor_mut(&mut pool);
assert_eq!(cursor.index(), Some(0));
cursor.move_next(&mut pool);
assert_eq!(cursor.index(), None); // Past the endSourcepub fn peek<'p>(&self, pool: &'p ElemPool<T>) -> Option<&'p T>
pub fn peek<'p>(&self, pool: &'p ElemPool<T>) -> Option<&'p T>
Provides a reference to the element at the cursor’s current position.
Returns None if the cursor is “Before Start” or “After End”.
§Example
let mut cursor = list.cursor_mut(&mut pool);
assert_eq!(cursor.peek(&pool), Some(&10));Sourcepub fn peek_mut<'p>(&mut self, pool: &'p mut ElemPool<T>) -> Option<&'p mut T>
pub fn peek_mut<'p>(&mut self, pool: &'p mut ElemPool<T>) -> Option<&'p mut T>
Provides a mutable reference to the element at the cursor’s current position.
Returns None if the cursor is “Before Start” or “After End”.
§Example
let mut cursor = list.cursor_mut(&mut pool);
if let Some(value) = cursor.peek_mut(&mut pool) {
*value = 99;
}
assert_eq!(list.front(&pool), Some(&99));Sourcepub fn move_next(&mut self, pool: &ElemPool<T>)
pub fn move_next(&mut self, pool: &ElemPool<T>)
Moves the cursor to the next element in the list.
- If “Before Start”: Moves to the first element (Head).
- If at the last element: Moves to “After End”.
- If “After End”: Stays at “After End” (no-op).
Sourcepub fn move_prev(&mut self, pool: &ElemPool<T>)
pub fn move_prev(&mut self, pool: &ElemPool<T>)
Moves the cursor to the previous element in the list.
- If “After End”: Moves to the last element (Tail).
- If at the first element: Moves to “Before Start”.
- If “Before Start”: Stays at “Before Start” (no-op).
Sourcepub fn move_to_front(&mut self, pool: &ElemPool<T>)
pub fn move_to_front(&mut self, pool: &ElemPool<T>)
Moves the cursor to the first element of the list.
If the list is empty, results in “After End” (index 0, len 0).
Sourcepub fn move_to_back(&mut self, pool: &ElemPool<T>)
pub fn move_to_back(&mut self, pool: &ElemPool<T>)
Moves the cursor to the last element of the list.
If the list is empty, results in “After End” (index 0, len 0).
Sourcepub fn insert_before(
&mut self,
data: T,
pool: &mut ElemPool<T>,
) -> Result<(), IndexError>
pub fn insert_before( &mut self, data: T, pool: &mut ElemPool<T>, ) -> Result<(), IndexError>
Inserts a new element before the cursor’s current position.
- If valid position: Inserts before. Cursor points to new element.
- If “After End”: Appends to list. Cursor points to new element (the new tail).
- If “Before Start”: Prepends to list. Cursor points to new element (the new head).
§Complexity
O(1)
§Errors
Returns IndexError if the pool fails to allocate a new element.
§Example
// Cursor is at index 0 (value 30)
let mut cursor = list.cursor_mut(&mut pool);
cursor.insert_before(20, &mut pool).unwrap();
// Cursor is now at the new element '20', which is at index 0
assert_eq!(cursor.index(), Some(0));
assert_eq!(*cursor.peek_mut(&mut pool).unwrap(), 20);
let vec: Vec<_> = list.iter(&pool).copied().collect();
assert_eq!(vec, vec![20, 30]);Sourcepub fn insert_after(
&mut self,
data: T,
pool: &mut ElemPool<T>,
) -> Result<(), IndexError>
pub fn insert_after( &mut self, data: T, pool: &mut ElemPool<T>, ) -> Result<(), IndexError>
Inserts a new element after the cursor’s current position.
- If valid position: Inserts after. Cursor stays on current element.
- If “After End”: No-op logic (Appends? Undefined?). Currently acts like append.
- If “Before Start”: Prepends to list. Cursor stays “Before Start”.
§Complexity
O(1)
§Example
// Cursor is at index 0 (value 10)
let mut cursor = list.cursor_mut(&mut pool);
cursor.insert_after(20, &mut pool).unwrap();
// Cursor is still at index 0 (value 10)
assert_eq!(cursor.index(), Some(0));
assert_eq!(*cursor.peek_mut(&mut pool).unwrap(), 10);
let vec: Vec<_> = list.iter(&pool).copied().collect();
assert_eq!(vec, vec![10, 20]);Sourcepub fn remove_current(&mut self, pool: &mut ElemPool<T>) -> Option<T>
pub fn remove_current(&mut self, pool: &mut ElemPool<T>) -> Option<T>
Removes the element at the cursor’s current position and returns its data.
After removal, the cursor moves to the next element. If the removed element was the last one, the cursor moves to the “After End” position.
§Returns
Some(T) if an element was removed, None if the cursor was not on a
valid element (i.e. Before Start or After End).
§Example
// Cursor at index 0 (value 10)
let mut cursor = list.cursor_mut(&mut pool);
let removed = cursor.remove_current(&mut pool);
assert_eq!(removed, Some(10));
// Cursor is now at the next element (20), which shifted to index 0
assert_eq!(cursor.index(), Some(0));
assert_eq!(*cursor.peek_mut(&mut pool).unwrap(), 20);Sourcepub fn split_before(
&mut self,
pool: &mut ElemPool<T>,
) -> Result<PieList<T>, IndexError>
pub fn split_before( &mut self, pool: &mut ElemPool<T>, ) -> Result<PieList<T>, IndexError>
Splits the list into two at the cursor’s current position.
The original list (self) is modified to contain all elements from the
current position onwards. A new PieList is returned containing all
elements before the current position.
§Example
let mut front_list;
{
// Cursor at index 1 (value 20)
let mut cursor = list.cursor_mut_at(1, &mut pool).unwrap();
// Split. front_list gets {10}. Original keeps {20}.
front_list = cursor.split_before(&mut pool).unwrap();
// Cursor points to 20, which is now index 0 of the truncated list
assert_eq!(cursor.index(), Some(0));
}
assert_eq!(list.len(), 1);
assert_eq!(front_list.len(), 1);Sourcepub fn splice_before(
&mut self,
other: &mut PieList<T>,
pool: &mut ElemPool<T>,
) -> Result<(), IndexError>
pub fn splice_before( &mut self, other: &mut PieList<T>, pool: &mut ElemPool<T>, ) -> Result<(), IndexError>
Moves all elements from other into self’s list, inserting them
just before the cursor’s current position.
After the operation, other is left empty.
§Example
let mut list1 = PieList::new(&mut pool);
list1.push_back(30, &mut pool).unwrap();
let mut list2 = PieList::new(&mut pool);
list2.push_back(10, &mut pool).unwrap();
list2.push_back(20, &mut pool).unwrap();
{
// Cursor at 30
let mut cursor = list1.cursor_mut(&mut pool);
cursor.splice_before(&mut list2, &mut pool).unwrap();
// list1: {10, 20, 30}. Cursor still at 30, now index 2.
assert_eq!(cursor.index(), Some(2));
}
assert_eq!(list1.len(), 3);
assert!(list2.is_empty());