use crate::test::drop_tracker::DropTracker;
use crate::test::types::{Sixteen, Three};
use enumoid::EnumOptionMap;
use enumoid::EnumSize;
use enumoid::EnumVec;
use std::cell::Cell;
#[test]
fn test_empty_state() {
let vec = EnumVec::<Three, u16>::new();
assert!(vec.is_empty(), "Expected new vec to be empty");
assert!(!vec.is_full(), "Expected new vec to not be full");
assert_eq!(
vec.size(),
EnumSize::EMPTY,
"Expected new vec to have empty size"
);
assert!(
!vec.contains(Three::A),
"Expected new vec to not contain Three::A"
);
assert!(
!vec.contains(Three::B),
"Expected new vec to not contain Three::B"
);
assert!(
!vec.contains(Three::C),
"Expected new vec to not contain Three::C"
);
assert!(
!vec.contains_index(Three::A.into()),
"Expected new vec to not contain index A"
);
assert!(
!vec.contains_index(Three::B.into()),
"Expected new vec to not contain index B"
);
assert!(
!vec.contains_index(Three::C.into()),
"Expected new vec to not contain index C"
);
assert_eq!(
vec.get(Three::A),
None,
"Expected get() to return None for empty vec"
);
assert_eq!(
vec.get(Three::B),
None,
"Expected get() to return None for empty vec"
);
assert_eq!(
vec.get(Three::C),
None,
"Expected get() to return None for empty vec"
);
assert_eq!(
vec.get_by_index(Three::A.into()),
None,
"Expected get_by_index() to return None for empty vec"
);
assert_eq!(
vec.get_by_index(Three::B.into()),
None,
"Expected get_by_index() to return None for empty vec"
);
assert_eq!(
vec.get_by_index(Three::C.into()),
None,
"Expected get_by_index() to return None for empty vec"
);
let collected: Vec<_> = vec.iter().collect();
assert_eq!(collected, vec![], "Expected empty iteration for empty vec");
}
#[test]
fn test_push_pop() {
let mut vec = EnumVec::<Three, u16>::new();
assert_eq!(
vec.pop(),
None,
"Expected pop() to return None for empty vec"
);
vec
.try_push(100)
.expect("Failed to push first element to empty vec");
assert!(!vec.is_empty(), "Expected vec to not be empty after push");
assert!(!vec.is_full(), "Expected vec to not be full after one push");
assert_eq!(
vec[Three::A],
100,
"Expected index access to return pushed value"
);
assert_eq!(
vec.size(),
EnumSize::from_last(Three::A),
"Expected size to reflect one element"
);
vec
.try_push(200)
.expect("Failed to push second element to vec");
assert_eq!(
vec[Three::A],
100,
"Expected first element to remain unchanged"
);
assert_eq!(
vec[Three::B],
200,
"Expected second element to be accessible"
);
assert_eq!(
vec.size(),
EnumSize::from_last(Three::B),
"Expected size to reflect two elements"
);
vec
.try_push(300)
.expect("Failed to push third element to vec");
assert!(
vec.is_full(),
"Expected vec to be full after pushing all elements"
);
assert_eq!(
vec[Three::C],
300,
"Expected third element to be accessible"
);
assert_eq!(
vec.size(),
EnumSize::from_last(Three::C),
"Expected size to reflect three elements"
);
assert_eq!(
vec.pop(),
Some(300),
"Expected pop() to return last pushed value"
);
assert!(!vec.is_full(), "Expected vec to not be full after pop");
assert_eq!(
vec.get(Three::C),
None,
"Expected get() to return None for popped element"
);
assert_eq!(
vec.size(),
EnumSize::from_last(Three::B),
"Expected size to reflect pop"
);
vec[Three::B] += 1;
assert_eq!(
vec[Three::B],
201,
"Expected mutable indexing to modify value"
);
}
#[test]
fn test_new_with_constructor() {
let vec =
EnumVec::<Three, i32>::new_with(EnumSize::from_last(Three::B), |variant| {
match variant {
Three::A => 10,
Three::B => 20,
Three::C => 30,
}
});
assert_eq!(
vec.size(),
EnumSize::from_last(Three::B),
"Expected size to match constructor parameter"
);
assert_eq!(vec[Three::A], 10, "Expected correct value for Three::A");
assert_eq!(vec[Three::B], 20, "Expected correct value for Three::B");
assert_eq!(
vec.get(Three::C),
None,
"Expected None for Three::C since it's beyond size"
);
let full_vec =
EnumVec::<Three, i32>::new_with(EnumSize::from_last(Three::C), |variant| {
match variant {
Three::A => 100,
Three::B => 200,
Three::C => 300,
}
});
assert!(full_vec.is_full(), "Expected full vec to be full");
assert_eq!(
full_vec[Three::A],
100,
"Expected correct value for Three::A in full vec"
);
assert_eq!(
full_vec[Three::B],
200,
"Expected correct value for Three::B in full vec"
);
assert_eq!(
full_vec[Three::C],
300,
"Expected correct value for Three::C in full vec"
);
}
#[test]
fn test_get_methods() {
let mut vec: EnumVec<Three, i32> = [42, 84].into_iter().collect();
assert_eq!(
vec.get(Three::A),
Some(&42),
"Expected get() to return reference to first element"
);
assert_eq!(
vec.get(Three::B),
Some(&84),
"Expected get() to return reference to second element"
);
assert_eq!(
vec.get(Three::C),
None,
"Expected get() to return None for index beyond size"
);
assert_eq!(
vec.get_by_index(Three::A.into()),
Some(&42),
"Expected get_by_index() to return reference to first element"
);
assert_eq!(
vec.get_by_index(Three::B.into()),
Some(&84),
"Expected get_by_index() to return reference to second element"
);
assert_eq!(
vec.get_by_index(Three::C.into()),
None,
"Expected get_by_index() to return None for index beyond size"
);
*vec
.get_mut(Three::A)
.expect("Expected get_mut to return Some for existing element") = 100;
assert_eq!(
vec[Three::A],
100,
"Expected value to be modified through get_mut()"
);
*vec
.get_by_index_mut(Three::B.into())
.expect("Expected get_by_index_mut to return Some for existing element") =
200;
assert_eq!(
vec[Three::B],
200,
"Expected value to be modified through get_by_index_mut()"
);
assert_eq!(
vec.get_mut(Three::C),
None,
"Expected get_mut() to return None for index beyond size"
);
assert_eq!(
vec.get_by_index_mut(Three::C.into()),
None,
"Expected get_by_index_mut() to return None for index beyond size"
);
}
#[test]
fn test_contains() {
let vec = EnumVec::<Three, i32>::new();
assert!(
!vec.contains(Three::A),
"Expected empty vec to not contain Three::A"
);
assert!(
!vec.contains(Three::B),
"Expected empty vec to not contain Three::B"
);
assert!(
!vec.contains(Three::C),
"Expected empty vec to not contain Three::C"
);
let mut vec_with_one: EnumVec<Three, i32> = [10].into_iter().collect();
assert!(
vec_with_one.contains(Three::A),
"Expected vec to contain Three::A"
);
assert!(
!vec_with_one.contains(Three::B),
"Expected vec to not contain Three::B"
);
assert!(
!vec_with_one.contains(Three::C),
"Expected vec to not contain Three::C"
);
vec_with_one
.try_push(20)
.expect("Failed to push second element in contains test");
assert!(
vec_with_one.contains(Three::A),
"Expected vec to contain Three::A"
);
assert!(
vec_with_one.contains(Three::B),
"Expected vec to contain Three::B"
);
assert!(
!vec_with_one.contains(Three::C),
"Expected vec to not contain Three::C"
);
assert!(
vec_with_one.contains_index(Three::A.into()),
"Expected vec to contain index A"
);
assert!(
vec_with_one.contains_index(Three::B.into()),
"Expected vec to contain index B"
);
assert!(
!vec_with_one.contains_index(Three::C.into()),
"Expected vec to not contain index C"
);
}
#[test]
fn test_clear() {
let mut vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
assert!(vec.is_full(), "Expected vec to be full before clear");
assert_eq!(
vec.size(),
EnumSize::from_last(Three::C),
"Expected size to be full before clear"
);
vec.clear();
assert!(vec.is_empty(), "Expected vec to be empty after clear");
assert_eq!(
vec.size(),
EnumSize::EMPTY,
"Expected size to be empty after clear"
);
assert_eq!(
vec.get(Three::A),
None,
"Expected get() to return None after clear"
);
assert_eq!(
vec.get(Three::B),
None,
"Expected get() to return None after clear"
);
assert_eq!(
vec.get(Three::C),
None,
"Expected get() to return None after clear"
);
vec
.try_push(100)
.expect("Failed to push element after clear");
assert_eq!(
vec[Three::A],
100,
"Expected to be able to push after clear"
);
assert_eq!(
vec.size(),
EnumSize::from_last(Three::A),
"Expected size to reflect new element after clear"
);
}
#[test]
fn test_remove_at_index() {
let mut vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let removed = vec.remove_at_index(Three::B.into());
assert_eq!(
removed,
Some(20),
"Expected remove_at_index() to return removed value"
);
assert_eq!(
vec.size(),
EnumSize::from_last(Three::B),
"Expected size to decrease after remove"
);
assert_eq!(
vec[Three::A],
10,
"Expected first element to remain unchanged"
);
assert_eq!(
vec[Three::B],
30,
"Expected third element to shift down to second position"
);
assert_eq!(
vec.get(Three::C),
None,
"Expected get() to return None for index beyond new size"
);
let removed = vec.remove_at_index(Three::C.into());
assert_eq!(
removed, None,
"Expected remove_at_index() to return None for out-of-bounds index"
);
assert_eq!(
vec.size(),
EnumSize::from_last(Three::B),
"Expected size to remain unchanged after failed remove"
);
}
#[test]
fn test_swap_remove_at_index() {
let mut vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let removed = vec.swap_remove_at_index(Three::A.into());
assert_eq!(
removed,
Some(10),
"Expected swap_remove_at_index() to return removed value"
);
assert_eq!(
vec.size(),
EnumSize::from_last(Three::B),
"Expected size to decrease after swap_remove"
);
assert_eq!(
vec[Three::A],
30,
"Expected first element to be replaced with last element"
);
assert_eq!(
vec[Three::B],
20,
"Expected second element to remain unchanged"
);
assert_eq!(
vec.get(Three::C),
None,
"Expected get() to return None for index beyond new size"
);
let removed = vec.swap_remove_at_index(Three::C.into());
assert_eq!(
removed, None,
"Expected swap_remove_at_index() to return None for out-of-bounds index"
);
assert_eq!(
vec.size(),
EnumSize::from_last(Three::B),
"Expected size to remain unchanged after failed swap_remove"
);
}
#[test]
fn test_slice_access() {
let mut vec: EnumVec<Three, i32> = [10, 20].into_iter().collect();
let slice = vec.as_slice();
assert_eq!(
slice,
&[10, 20],
"Expected slice to contain all values in order"
);
{
let slice_mut = vec.as_slice_mut();
slice_mut[0] = 100;
assert_eq!(
slice_mut.len(),
2,
"Expected slice length to match vec size"
);
}
assert_eq!(
vec[Three::A],
100,
"Expected value change through mutable slice"
);
}
#[test]
fn test_iteration_elements_in_order() {
let vec = EnumVec::<Three, i32>::new();
let collected: Vec<_> = vec.iter().collect();
assert_eq!(collected, vec![], "Expected empty iteration for empty vec");
let mut vec: EnumVec<Three, i32> = [10, 20].into_iter().collect();
let collected: Vec<_> = vec.iter().collect();
assert_eq!(
collected,
vec![(Three::A, &10), (Three::B, &20)],
"Expected iteration to yield key-value pairs in order"
);
for (_, value) in vec.iter_mut() {
*value *= 10;
}
let collected: Vec<_> = vec.iter().collect();
assert_eq!(
collected,
vec![(Three::A, &100), (Three::B, &200)],
"Expected values to be modified through iter_mut()"
);
}
#[test]
fn test_iterator_exact_size_and_double_ended() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let mut iter = vec.iter();
assert_eq!(iter.len(), 3, "Expected iterator length to be 3");
assert_eq!(iter.size_hint(), (3, Some(3)), "Expected correct size hint");
assert_eq!(
iter.nth(1),
Some((Three::B, &20)),
"Expected nth(1) to return second element"
);
assert_eq!(
iter.len(),
1,
"Expected iterator length to be 1 after nth(1)"
);
let mut iter = vec.iter();
assert_eq!(
iter.next_back(),
Some((Three::C, &30)),
"Expected next_back() to return last element"
);
assert_eq!(
iter.next_back(),
Some((Three::B, &20)),
"Expected next_back() to return second-to-last element"
);
assert_eq!(
iter.next(),
Some((Three::A, &10)),
"Expected next() to return first element"
);
assert_eq!(iter.next(), None, "Expected iterator to be exhausted");
assert_eq!(vec.iter().count(), 3, "Expected iterator count to be 3");
let empty_vec = EnumVec::<Three, i32>::new();
let empty_iter = empty_vec.iter();
assert_eq!(
empty_iter.len(),
0,
"Expected empty iterator length to be 0"
);
assert!(empty_iter.len() == 0, "Expected empty iterator to be empty");
assert_eq!(
empty_iter.size_hint(),
(0, Some(0)),
"Expected correct size hint for empty iterator"
);
}
#[test]
fn test_into_iterator() {
let mut vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let collected: Vec<_> = (&vec).into_iter().collect();
assert_eq!(
collected,
vec![(Three::A, &10), (Three::B, &20), (Three::C, &30)],
"Expected IntoIterator to work for &EnumVec"
);
let collected_mut: Vec<_> =
(&mut vec).into_iter().map(|(k, v)| (k, *v)).collect();
assert_eq!(
collected_mut,
vec![(Three::A, 10), (Three::B, 20), (Three::C, 30)],
"Expected IntoIterator to work for &mut EnumVec"
);
let mut sum = 0;
for (_, value) in &vec {
sum += *value;
}
assert_eq!(sum, 60, "Expected for loop to sum all values");
for (_, value) in &mut vec {
*value += 1;
}
let collected: Vec<_> = vec.iter().collect();
assert_eq!(
collected,
vec![(Three::A, &11), (Three::B, &21), (Three::C, &31)],
"Expected values to be modified through mutable for loop"
);
}
#[test]
fn test_from_iterator() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
assert_eq!(vec[Three::A], 10, "Expected first element from iterator");
assert_eq!(vec[Three::B], 20, "Expected second element from iterator");
assert_eq!(vec[Three::C], 30, "Expected third element from iterator");
assert!(
vec.is_full(),
"Expected vec to be full after collecting all elements"
);
let partial_vec: EnumVec<Three, i32> = [100, 200].into_iter().collect();
assert_eq!(
partial_vec[Three::A],
100,
"Expected first element in partial vec"
);
assert_eq!(
partial_vec[Three::B],
200,
"Expected second element in partial vec"
);
assert_eq!(
partial_vec.get(Three::C),
None,
"Expected no third element in partial vec"
);
let empty_vec: EnumVec<Three, i32> = std::iter::empty().collect();
assert!(
empty_vec.is_empty(),
"Expected empty vec from empty iterator"
);
}
#[test]
fn test_extend() {
let mut vec = EnumVec::<Three, i32>::new();
vec.try_push(10).unwrap();
vec.extend([20, 30]);
assert_eq!(vec[Three::A], 10, "Expected preexisting element");
assert_eq!(vec[Three::B], 20, "Expected first extended element");
assert_eq!(vec[Three::C], 30, "Expected second extended element");
assert!(vec.is_full(), "Expected vec to be full after extending");
}
#[test]
fn test_extend_overflow() {
let mut vec = EnumVec::<Three, i32>::new();
vec.extend([10, 20, 30, 40, 50]);
assert!(
vec.is_full(),
"Expected vec to be full after extending beyond capacity"
);
assert_eq!(vec[Three::C], 30, "Expected last in-capacity element");
}
#[test]
fn test_from_iterator_overflow() {
let mut iter = [10, 20, 30, 40, 50].into_iter();
let vec: EnumVec<Three, i32> = iter.by_ref().collect();
assert!(
vec.is_full(),
"Expected vec to be full after collecting beyond capacity"
);
assert_eq!(vec[Three::A], 10, "Expected first element");
assert_eq!(vec[Three::B], 20, "Expected second element");
assert_eq!(vec[Three::C], 30, "Expected third element");
let remaining: Vec<i32> = iter.collect();
assert_eq!(
remaining,
vec![50],
"Expected collect to stop pulling once the vec is full"
);
}
#[test]
fn test_iterator_partial_consumption() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let mut iter = vec.iter();
assert_eq!(iter.next(), Some((Three::A, &10)), "Expected first element");
assert_eq!(iter.len(), 2, "Expected length to decrease after next()");
let remaining: Vec<_> = iter.collect();
assert_eq!(
remaining,
vec![(Three::B, &20), (Three::C, &30)],
"Expected remaining elements after partial consumption"
);
}
#[test]
fn test_iterator_single_element() {
let vec: EnumVec<Three, i32> = [42].into_iter().collect();
let collected: Vec<_> = vec.iter().collect();
assert_eq!(
collected,
vec![(Three::A, &42)],
"Expected single element iteration"
);
let mut iter = vec.iter();
assert_eq!(iter.len(), 1, "Expected single element iterator length");
assert_eq!(
iter.next(),
Some((Three::A, &42)),
"Expected single element"
);
assert_eq!(iter.next(), None, "Expected iterator to be exhausted");
assert_eq!(iter.len(), 0, "Expected exhausted iterator length to be 0");
}
#[test]
fn test_swap_elements() {
let mut vec: EnumVec<Sixteen, u16> = [1, 2, 3, 4, 5].into_iter().collect();
vec.swap(Sixteen::B, Sixteen::D);
let collected: Vec<u16> = vec.iter().map(|x| *x.1).collect();
assert_eq!(collected, vec![1, 4, 3, 2, 5]);
}
#[test]
fn test_swap_remove() {
let mut vec: EnumVec<Sixteen, u16> = [1, 2, 3, 4, 5].into_iter().collect();
assert_eq!(vec.swap_remove(Sixteen::F), None);
assert_eq!(vec.swap_remove(Sixteen::B), Some(2));
let collected: Vec<u16> = vec.iter().map(|x| *x.1).collect();
assert_eq!(collected, vec![1, 5, 3, 4]);
}
#[test]
fn test_remove() {
let mut vec: EnumVec<Sixteen, u16> = [1, 2, 3, 4, 5].into_iter().collect();
assert_eq!(vec.remove(Sixteen::F), None);
assert_eq!(vec.remove(Sixteen::B), Some(2));
let collected: Vec<u16> = vec.iter().map(|x| *x.1).collect();
assert_eq!(collected, vec![1, 3, 4, 5]);
}
#[test]
fn test_push() {
let mut vec = EnumVec::<Three, u16>::new();
vec
.try_push(100)
.expect("Failed to push first element in push test");
vec
.try_push(200)
.expect("Failed to push second element in push test");
vec
.try_push(300)
.expect("Failed to push third element in push test");
let overflow = vec.try_push(400);
assert_eq!(overflow, Err(400), "Expected overflow to return the value");
}
#[test]
#[should_panic(expected = "index out of bounds")]
fn test_swap_out_of_bounds_panics() {
let mut vec = EnumVec::<Three, u16>::new();
vec.swap(Three::A, Three::C);
}
#[test]
fn test_try_from_contiguous_option_map() {
let mut opt = EnumOptionMap::<Three, i32>::new();
opt.insert(Three::A, 10);
opt.insert(Three::B, 20);
let vec = EnumVec::try_from(opt)
.expect("Expected Ok when option map is a contiguous prefix");
assert_eq!(vec[Three::A], 10, "Expected converted value for A");
assert_eq!(vec[Three::B], 20, "Expected converted value for B");
assert_eq!(vec.get(Three::C), None, "Expected C to be absent");
}
#[test]
fn test_try_from_gapped_option_map_fails() {
let mut opt = EnumOptionMap::<Three, i32>::new();
opt.insert(Three::A, 10);
opt.insert(Three::C, 30);
assert_eq!(
EnumVec::try_from(opt),
Err(()),
"Expected Err when option map is not a contiguous prefix"
);
}
#[test]
fn test_into_iterator_owned() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let collected: Vec<i32> = vec.into_iter().collect();
assert_eq!(
collected,
vec![10, 20, 30],
"Expected consuming iteration to yield owned values in order"
);
}
#[test]
fn test_into_iterator_owned_partial() {
let vec: EnumVec<Three, i32> = [10, 20].into_iter().collect();
let collected: Vec<i32> = vec.into_iter().collect();
assert_eq!(
collected,
vec![10, 20],
"Expected consuming iteration to yield only the populated prefix"
);
}
#[test]
fn test_into_iterator_owned_roundtrips() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let roundtripped: EnumVec<Three, i32> = vec.into_iter().collect();
let expected: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
assert_eq!(
roundtripped, expected,
"Expected into_iter().collect() to round-trip"
);
}
#[test]
fn test_into_iterator_owned_exact_size() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let mut iter = vec.into_iter();
assert_eq!(iter.len(), 3, "Expected ExactSizeIterator len of 3");
assert_eq!(iter.size_hint(), (3, Some(3)), "Expected exact size hint");
iter.next();
assert_eq!(iter.len(), 2, "Expected len to decrease after next()");
}
#[test]
fn test_into_iterator_owned_drops_all_when_consumed() {
let drops = Cell::new(0);
let vec: EnumVec<Three, DropTracker> = [
DropTracker::new(1, &drops),
DropTracker::new(2, &drops),
DropTracker::new(3, &drops),
]
.into_iter()
.collect();
let ids: Vec<i32> = vec.into_iter().map(|t| t.id()).collect();
assert_eq!(ids, vec![1, 2, 3], "Expected ids in order");
assert_eq!(
drops.get(),
3,
"Expected each yielded element to be dropped exactly once"
);
}
#[test]
fn test_into_iterator_owned_drops_remainder_when_abandoned() {
let drops = Cell::new(0);
let vec: EnumVec<Three, DropTracker> = [
DropTracker::new(1, &drops),
DropTracker::new(2, &drops),
DropTracker::new(3, &drops),
]
.into_iter()
.collect();
let mut iter = vec.into_iter();
{
let first = iter.next().expect("Expected a first element");
assert_eq!(first.id(), 1, "Expected first element id");
assert_eq!(drops.get(), 0, "Expected no drops while first is held");
}
assert_eq!(drops.get(), 1, "Expected the moved-out element to drop");
drop(iter);
assert_eq!(
drops.get(),
3,
"Expected the two unyielded elements to drop when abandoned"
);
}
#[test]
fn test_into_iterator_owned_double_ended() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let mut iter = vec.into_iter();
assert_eq!(
iter.next_back(),
Some(30),
"Expected next_back() to yield the last element"
);
assert_eq!(
iter.next(),
Some(10),
"Expected next() to yield the first element"
);
assert_eq!(
iter.next_back(),
Some(20),
"Expected next_back() to yield the remaining middle element"
);
assert_eq!(iter.next(), None, "Expected exhaustion from the front");
assert_eq!(iter.next_back(), None, "Expected exhaustion from the back");
}
#[test]
fn test_into_iterator_owned_double_ended_partial() {
let vec: EnumVec<Three, i32> = [10, 20].into_iter().collect();
let collected: Vec<i32> = vec.into_iter().rev().collect();
assert_eq!(
collected,
vec![20, 10],
"Expected reversed iteration over only the populated prefix"
);
}
#[test]
fn test_into_iterator_owned_rev() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let collected: Vec<i32> = vec.into_iter().rev().collect();
assert_eq!(
collected,
vec![30, 20, 10],
"Expected reversed iteration to yield values in reverse order"
);
}
#[test]
fn test_into_iterator_owned_double_ended_exact_size() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let mut iter = vec.into_iter();
assert_eq!(iter.len(), 3, "Expected initial len of 3");
iter.next();
assert_eq!(iter.len(), 2, "Expected len 2 after next()");
iter.next_back();
assert_eq!(iter.len(), 1, "Expected len 1 after next_back()");
iter.next();
assert_eq!(iter.len(), 0, "Expected len 0 once the ends meet");
}
#[test]
fn test_into_iterator_owned_fused() {
let vec: EnumVec<Three, i32> = [10, 20, 30].into_iter().collect();
let mut iter = vec.into_iter();
for _ in 0..3 {
assert!(
iter.next().is_some(),
"Expected three elements before exhaustion"
);
}
assert_eq!(iter.next(), None, "Expected None once exhausted");
assert_eq!(iter.next(), None, "Expected fused None on repeat next()");
assert_eq!(
iter.next_back(),
None,
"Expected fused None from the back once exhausted"
);
}
#[test]
fn test_into_iterator_owned_double_ended_drops_remainder() {
let drops = Cell::new(0);
let vec: EnumVec<Three, DropTracker> = [
DropTracker::new(1, &drops),
DropTracker::new(2, &drops),
DropTracker::new(3, &drops),
]
.into_iter()
.collect();
let mut iter = vec.into_iter();
{
let front = iter.next().expect("Expected a front element");
let back = iter.next_back().expect("Expected a back element");
assert_eq!(front.id(), 1, "Expected front element id");
assert_eq!(back.id(), 3, "Expected back element id");
assert_eq!(drops.get(), 0, "Expected no drops while elements are held");
}
assert_eq!(
drops.get(),
2,
"Expected the two moved-out elements to drop"
);
drop(iter);
assert_eq!(
drops.get(),
3,
"Expected the single unyielded middle element to drop exactly once"
);
}
#[test]
fn test_iter_mut_double_ended() {
let mut vec: EnumVec<Three, u16> = [10, 20, 30].into_iter().collect();
{
let mut iter = vec.iter_mut();
let (back_key, back_value) =
iter.next_back().expect("Expected a back element");
assert_eq!(back_key, Three::C, "Expected next_back() key to be C");
*back_value += 1;
let (front_key, front_value) =
iter.next().expect("Expected a front element");
assert_eq!(front_key, Three::A, "Expected next() key to be A");
*front_value += 1;
assert_eq!(
iter.next_back().map(|(k, v)| (k, *v)),
Some((Three::B, 20)),
"Expected next_back() to yield the middle element"
);
assert!(iter.next().is_none(), "Expected the ends to have met");
assert!(
iter.next_back().is_none(),
"Expected fused None from the back"
);
}
assert_eq!(vec[Three::A], 11, "Expected front mutation to persist");
assert_eq!(vec[Three::C], 31, "Expected back mutation to persist");
}