From 0a8bad4d215786ec7b1212cbd0bf6b283071cfe5 Mon Sep 17 00:00:00 2001 From: soruh Date: Sun, 26 Jul 2026 14:41:22 +0200 Subject: [PATCH] add more tests --- src/lib.rs | 12 ++++++-- src/tests.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5d58360..5bba2b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,8 +85,6 @@ impl TypeErasedVec { /// # Safety /// The caller must ensure that the existing elements can be safely transmuted /// into the new type `T` and that dropping them as `T` is sound. - /// - /// The `Layout` of the new type `T` does not match the `Layout` of the allocated capacity pub unsafe fn cast_type(&mut self) -> ContentGuard<'_, T> { debug_assert_eq!(self.layout, Layout::new::()); @@ -168,6 +166,16 @@ impl TypeErasedVec { self.as_type::().take() } + /// Convert the capacity of the erased `Vec` into a `Vec`. + /// + /// # Safety + /// The caller must ensure that the existing elements can be safely transmuted + /// into the new type `T` and that dropping them as `T` is sound. + #[must_use] + pub unsafe fn cast_into_vec(mut self) -> Vec { + unsafe { self.cast_type::() }.take() + } + /// Convert the capacity of the erased `Vec` into a `Vec`. /// /// # Safety diff --git a/src/tests.rs b/src/tests.rs index 5f5033a..d5b03fb 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -290,3 +290,81 @@ fn test_drop_cleans_up_allocation() { assert_eq!(drop_count.get(), 1); } + +#[test] +fn test_guard_into_slice() { + let mut vec = Vec::::new(); + vec.push(1); + vec.push(2); + let mut erased = TypeErasedVec::new(vec); + + let guard = unsafe { erased.cast_type::() }; + let slice = guard.into_slice(); + assert_eq!(slice, &[1, 2]); +} + +#[test] +fn test_guard_into_slice_mut() { + let mut vec = Vec::::new(); + vec.push(1); + vec.push(2); + let mut erased = TypeErasedVec::new(vec); + + let guard = unsafe { erased.cast_type::() }; + let slice = guard.into_slice_mut(); + slice[0] = 99; + assert_eq!(slice, &[99, 2]); +} + +#[test] +fn test_guard_push() { + let vec = Vec::::new(); + let mut erased = TypeErasedVec::new(vec); + let mut guard = erased.as_type::(); + + guard.push(42); + assert_eq!(guard.length(), 1); + assert_eq!(guard.as_slice(), &[42]); +} + +#[test] +fn test_erased_layout_and_capacity_bytes() { + let vec = Vec::::with_capacity(8); + let erased = TypeErasedVec::new(vec); + + assert_eq!(erased.layout(), Layout::new::()); + assert_eq!(erased.capacity_bytes(), erased.capacity() * 8); +} + +#[test] +fn test_unchecked_methods() { + let mut vec = Vec::::new(); + vec.push(123); + let mut erased = TypeErasedVec::new(vec); + + let mut guard = unsafe { erased.cast_type::() }; + assert_eq!(guard.as_slice(), &[123]); + let restored = guard.take(); + assert_eq!(restored, vec![123]); + + let vec2 = Vec::::new(); + let erased2 = TypeErasedVec::new(vec2); + let restored2 = unsafe { erased2.into_vec_unchecked::() }; + assert!(restored2.is_empty()); +} + +#[test] +fn test_multiple_compatible_type_casts() { + let mut vec = Vec::::new(); + vec.push(-1); + let mut erased = TypeErasedVec::new(vec); + + { + let mut guard = unsafe { erased.cast_type::() }; + assert_eq!(guard.as_slice(), &[u32::MAX]); + guard.push(42); + } + + let restored = unsafe { erased.cast_into_vec::() }; + assert_eq!(restored, vec![-1, 42]); +}