Skip to content

Commit

Permalink
feat(cordyceps): add CursorMut::as_cursor (#244)
Browse files Browse the repository at this point in the history
This commit adds an `as_cursor` method to `cordyceps::list::CursorMut`
that temporarily borrows the `CursorMut` as an immutable
`Cursor`. This is the same as the `as_cursor` method on
`std::collections::linked_list`'s `CursorMut` type.
  • Loading branch information
hawkw authored Jun 25, 2022
1 parent 4efd66f commit 2a7ce9c
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 54 deletions.
16 changes: 16 additions & 0 deletions cordyceps/src/list/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,22 @@ impl<'list, T: Linked<Links<T>> + ?Sized> CursorMut<'list, T> {

self.core.index += splice_len;
}

/// Returns a read-only cursor pointing to the current element.
///
/// The lifetime of the returned [`Cursor`] is bound to that of the
/// `CursorMut`, which means it cannot outlive the `CursorMut` and that the
/// `CursorMut` is frozen for the lifetime of the [`Cursor`].
#[must_use]
pub fn as_cursor(&self) -> Cursor<'_, T> {
Cursor {
core: CursorCore {
list: self.core.list,
curr: self.core.curr,
index: self.core.index,
},
}
}
}

impl<T: Linked<Links<T>> + ?Sized> fmt::Debug for CursorMut<'_, T> {
Expand Down
135 changes: 81 additions & 54 deletions cordyceps/src/list/tests/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::*;
/// interface:
/// https://github.com/rust-lang/rust/blob/ec21d7ea3ca8e96863f175fbd4a6bfee79529d6c/library/alloc/src/collections/linked_list/tests.rs#L564-L655
#[test]
fn move_peek() {
fn move_peek_front() {
let _ = super::trace_init();

let entries = [entry(1), entry(2), entry(3), entry(4), entry(5), entry(6)];
Expand All @@ -26,6 +26,17 @@ fn move_peek() {
assert_eq!(val(cursor.peek_next()), Some(3));
assert_eq!(val(cursor.peek_prev()), Some(1));
assert_eq!(cursor.index(), Some(1));
}

/// Based on this test from the standard library's `linked_list::Cursor`
/// interface:
/// https://github.com/rust-lang/rust/blob/ec21d7ea3ca8e96863f175fbd4a6bfee79529d6c/library/alloc/src/collections/linked_list/tests.rs#L564-L655
#[test]
fn move_peek_back() {
let _ = super::trace_init();

let entries = [entry(1), entry(2), entry(3), entry(4), entry(5), entry(6)];
let mut list = list_from_iter(&entries);

let mut cursor = list.cursor_back_mut();
assert_eq!(val(cursor.current()), Some(6));
Expand All @@ -43,60 +54,76 @@ fn move_peek() {
assert_eq!(val(cursor.peek_next()), Some(6));
assert_eq!(val(cursor.peek_prev()), Some(4));
assert_eq!(cursor.index(), Some(4));
}

/// Based on this test from the standard library's `linked_list::Cursor`
/// interface:
/// https://github.com/rust-lang/rust/blob/ec21d7ea3ca8e96863f175fbd4a6bfee79529d6c/library/alloc/src/collections/linked_list/tests.rs#L564-L655
#[test]
fn as_cursor_move_peek_front() {
let _ = super::trace_init();

// let mut m: LinkedList<u32> = LinkedList::new();
// m.extend(&[1, 2, 3, 4, 5, 6]);
// let mut cursor = m.cursor_front_mut();
// assert_eq!(val(cursor.current()), Some(&mut 1));
// assert_eq!(val(cursor.peek_next()), Some(&mut 2));
// assert_eq!(val(cursor.peek_prev()), None);
// assert_eq!(cursor.index(), Some(0));
// cursor.move_prev();
// assert_eq!(val(cursor.current()), None);
// assert_eq!(val(cursor.peek_next()), Some(&mut 1));
// assert_eq!(val(cursor.peek_prev()), Some(&mut 6));
// assert_eq!(cursor.index(), None);
// cursor.move_next();
// cursor.move_next();
// assert_eq!(val(cursor.current()), Some(&mut 2));
// assert_eq!(val(cursor.peek_next()), Some(&mut 3));
// assert_eq!(val(cursor.peek_prev()), Some(&mut 1));
// assert_eq!(cursor.index(), Some(1));
// let mut cursor2 = cursor.as_cursor();
// assert_eq!(cursor2.current(), Some(&2));
// assert_eq!(cursor2.index(), Some(1));
// cursor2.move_next();
// assert_eq!(cursor2.current(), Some(&3));
// assert_eq!(cursor2.index(), Some(2));
// assert_eq!(val(cursor.current()), Some(&mut 2));
// assert_eq!(cursor.index(), Some(1));

// let mut m: LinkedList<u32> = LinkedList::new();
// m.extend(&[1, 2, 3, 4, 5, 6]);
// let mut cursor = m.cursor_back_mut();
// assert_eq!(val(cursor.current()), Some(&mut 6));
// assert_eq!(val(cursor.peek_next()), None);
// assert_eq!(val(cursor.peek_prev()), Some(&mut 5));
// assert_eq!(cursor.index(), Some(5));
// cursor.move_next();
// assert_eq!(val(cursor.current()), None);
// assert_eq!(val(cursor.peek_next()), Some(&mut 1));
// assert_eq!(val(cursor.peek_prev()), Some(&mut 6));
// assert_eq!(cursor.index(), None);
// cursor.move_prev();
// cursor.move_prev();
// assert_eq!(val(cursor.current()), Some(&mut 5));
// assert_eq!(val(cursor.peek_next()), Some(&mut 6));
// assert_eq!(val(cursor.peek_prev()), Some(&mut 4));
// assert_eq!(cursor.index(), Some(4));
// let mut cursor2 = cursor.as_cursor();
// assert_eq!(cursor2.current(), Some(&5));
// assert_eq!(cursor2.index(), Some(4));
// cursor2.move_prev();
// assert_eq!(cursor2.current(), Some(&4));
// assert_eq!(cursor2.index(), Some(3));
// assert_eq!(val(cursor.current()), Some(&mut 5));
// assert_eq!(cursor.index(), Some(4));
let entries = [entry(1), entry(2), entry(3), entry(4), entry(5), entry(6)];
let mut list = list_from_iter(&entries);
let mut cursor = list.cursor_front_mut();
assert_eq!(val(cursor.current()), Some(1));
assert_eq!(val(cursor.peek_next()), Some(2));
assert_eq!(val(cursor.peek_prev()), None);
assert_eq!(cursor.index(), Some(0));
cursor.move_prev();
assert_eq!(val(cursor.current()), None);
assert_eq!(val(cursor.peek_next()), Some(1));
assert_eq!(val(cursor.peek_prev()), Some(6));
assert_eq!(cursor.index(), None);
cursor.move_next();
cursor.move_next();
assert_eq!(val(cursor.current()), Some(2));
assert_eq!(val(cursor.peek_next()), Some(3));
assert_eq!(val(cursor.peek_prev()), Some(1));
assert_eq!(cursor.index(), Some(1));
let mut cursor2 = cursor.as_cursor();
assert_eq!(val(cursor2.current()), Some(2));
assert_eq!(cursor2.index(), Some(1));
cursor2.move_next();
assert_eq!(val(cursor2.current()), Some(3));
assert_eq!(cursor2.index(), Some(2));
assert_eq!(val(cursor.current()), Some(2));
assert_eq!(cursor.index(), Some(1));
}

/// Based on this test from the standard library's `linked_list::Cursor`
/// interface:
/// https://github.com/rust-lang/rust/blob/ec21d7ea3ca8e96863f175fbd4a6bfee79529d6c/library/alloc/src/collections/linked_list/tests.rs#L564-L655
#[test]
fn as_cursor_move_peek_back() {
let _ = super::trace_init();

let entries = [entry(1), entry(2), entry(3), entry(4), entry(5), entry(6)];
let mut list = list_from_iter(&entries);
let mut cursor = list.cursor_back_mut();
assert_eq!(val(cursor.current()), Some(6));
assert_eq!(val(cursor.peek_next()), None);
assert_eq!(val(cursor.peek_prev()), Some(5));
assert_eq!(cursor.index(), Some(5));
cursor.move_next();
assert_eq!(val(cursor.current()), None);
assert_eq!(val(cursor.peek_next()), Some(1));
assert_eq!(val(cursor.peek_prev()), Some(6));
assert_eq!(cursor.index(), None);
cursor.move_prev();
cursor.move_prev();
assert_eq!(val(cursor.current()), Some(5));
assert_eq!(val(cursor.peek_next()), Some(6));
assert_eq!(val(cursor.peek_prev()), Some(4));
assert_eq!(cursor.index(), Some(4));
let mut cursor2 = cursor.as_cursor();
assert_eq!(val(cursor2.current()), Some(5));
assert_eq!(cursor2.index(), Some(4));
cursor2.move_prev();
assert_eq!(val(cursor2.current()), Some(4));
assert_eq!(cursor2.index(), Some(3));
assert_eq!(val(cursor.current()), Some(5));
assert_eq!(cursor.index(), Some(4));
}

/// Based on this test from the standard library's `linked_list::CursorMut`
Expand Down

0 comments on commit 2a7ce9c

Please sign in to comment.