I’m not sure what the desired result is when the cursor is at the front or the back, and you pop from the front or back, respectively. Either it moves to the next/previous element or to the “ghost”.
I’m also noticing that there’s no convenient method for remove_current
-but-move-to-the-right. remove_current
is weirdly asymmetrical. The code above does the “move to the ghost” approach, but to mirror that I’d need something like
fn pop_front<T>(c: &mut linked_list::CursorMut<'_, T>) -> Option<T> {
let mut left = c.split_before();
let result = left.pop_front().or_else(|| { let r = c.remove_current(); c.move_prev(); r } );
c.splice_before(left);
result
}
or completely restructure the code to e.g.
fn pop_front<T>(c: &mut linked_list::CursorMut<'_, T>) -> Option<T> {
let mut left = c.split_before();
match left.pop_front() {
val@Some(_) => {
c.splice_before(left);
val
}
None => {
let val = c.remove_current();
c.move_prev();
val
}
}
}
Edit: Actually, the latter too, compared to a restructured pop_back
fn pop_back<T>(c: &mut linked_list::CursorMut<'_, T>) -> Option<T> {
let mut right = c.split_after();
match right.pop_back() {
val@Some(_) => {
c.splice_after(right);
val
}
None => c.remove_current(),
}
}
has the same kind of notational overhead (extra block + extra variable)