continue refactor

This commit is contained in:
2026-07-26 14:37:41 +02:00
parent eed774b566
commit f6a1132023
3 changed files with 35 additions and 19 deletions
+16
View File
@@ -47,6 +47,10 @@ impl<'vec, T> ContentGuard<'vec, T> {
self.erased.capacity()
}
pub fn push(&mut self, value: T) {
self.with(|vec| vec.push(value));
}
#[must_use]
pub fn length(&self) -> usize {
self.erased.length()
@@ -68,4 +72,16 @@ impl<'vec, T> ContentGuard<'vec, T> {
// SAFETY: The pointer and length correctly represent the currently initialized elements.
unsafe { self.erased.parts.as_slice_mut() }
}
#[must_use]
pub fn into_slice(self) -> &'vec [T] {
// SAFETY: The pointer and length correctly represent the currently initialized elements.
unsafe { self.erased.parts.as_slice() }
}
#[must_use]
pub fn into_slice_mut(self) -> &'vec mut [T] {
// SAFETY: The pointer and length correctly represent the currently initialized elements.
unsafe { self.erased.parts.as_slice_mut() }
}
}
+9 -9
View File
@@ -101,7 +101,7 @@ impl TypeErasedVec {
/// Clears all elements currently stored in the `TypeErasedVec`.
///
/// Will fail if `T` does not have the same `Layout` as the underlying capacity.
pub fn try_to_type<T>(&mut self) -> Option<ContentGuard<'_, T>> {
pub fn try_as_type<T>(&mut self) -> Option<ContentGuard<'_, T>> {
self.clear();
// SAFETY: The vector has been cleared, meaning there are no existing elements
// that could be invalidated or improperly dropped by the cast.
@@ -113,9 +113,9 @@ impl TypeErasedVec {
///
/// # Panics
/// Panics if `T` does not have the same `Layout` as the underlying capacity.
pub fn to_type<T>(&mut self) -> ContentGuard<'_, T> {
pub fn as_type<T>(&mut self) -> ContentGuard<'_, T> {
let layout = self.layout;
self.try_to_type().unwrap_or_else(|| {
self.try_as_type().unwrap_or_else(|| {
panic!(
"Target type layout must exactly match the erased layout. Capacity is reserved for {:?} but {} has {:?}",
layout,
@@ -130,13 +130,13 @@ impl TypeErasedVec {
///
/// # Safety
/// `T` must have the same `Layout` as the underlying capacity.
pub unsafe fn to_type_unchecked<T>(&mut self) -> ContentGuard<'_, T> {
pub unsafe fn as_type_unchecked<T>(&mut self) -> ContentGuard<'_, T> {
let layout = self.layout;
let res = self.try_to_type();
let res = self.try_as_type();
if cfg!(debug_assertions) && res.is_none() {
unreachable!(
"Calling `to_type_unchecked` with an incompatible layout is UB! Target type layout must exactly match the erased layout. Capacity is reserved for {:?} but {} has {:?}",
"Calling `as_type_unchecked` with an incompatible layout is UB! Target type layout must exactly match the erased layout. Capacity is reserved for {:?} but {} has {:?}",
layout,
std::any::type_name::<T>(),
Layout::new::<T>()
@@ -152,7 +152,7 @@ impl TypeErasedVec {
/// # Errors
/// Returns the original `TypeErasedVec` if `T` does not have the same `Layout`.
pub fn try_into_vec<T>(mut self) -> Result<Vec<T>, Self> {
if let Some(mut guard) = self.try_to_type::<T>() {
if let Some(mut guard) = self.try_as_type::<T>() {
Ok(guard.take())
} else {
Err(self)
@@ -165,7 +165,7 @@ impl TypeErasedVec {
/// Panics if `T` does not have the same `Layout` as the underlying capacity.
#[must_use]
pub fn into_vec<T>(mut self) -> Vec<T> {
self.to_type::<T>().take()
self.as_type::<T>().take()
}
/// Convert the capacity of the erased `Vec` into a `Vec<T>`.
@@ -175,7 +175,7 @@ impl TypeErasedVec {
#[must_use]
pub unsafe fn into_vec_unchecked<T>(mut self) -> Vec<T> {
// SAFETY: Ensured by the caller.
unsafe { self.to_type_unchecked().take() }
unsafe { self.as_type_unchecked().take() }
}
/// Clear a type erased vec allowing it be safely shared across threads, preserving the capacity
+10 -10
View File
@@ -128,7 +128,7 @@ fn test_cast_type_success_and_mutation() {
}
#[test]
fn test_try_to_type_clears_elements() {
fn test_try_as_type_clears_elements() {
let drop_count = Rc::new(Cell::new(0));
let mut vec = Vec::with_capacity(5);
@@ -140,8 +140,8 @@ fn test_try_to_type_clears_elements() {
let mut erased = TypeErasedVec::new(vec);
assert_erased_state(&erased, 3, Layout::new::<DropTracker>());
let Some(guard) = erased.try_to_type::<DropTracker>() else {
panic!("try_to_type failed despite matching layouts");
let Some(guard) = erased.try_as_type::<DropTracker>() else {
panic!("try_as_type failed despite matching layouts");
};
assert_guard_state(&guard, 0);
@@ -190,7 +190,7 @@ fn test_conversion_methods() {
assert!(restored.capacity() >= initial_cap);
let mut erased2 = TypeErasedVec::new(restored);
let mut guard = erased2.to_type::<String>();
let mut guard = erased2.as_type::<String>();
guard.reserve(20);
let new_cap = guard.capacity();
@@ -222,10 +222,10 @@ fn test_try_into_vec_failure_and_recovery() {
#[test]
#[should_panic(expected = "Target type layout must exactly match")]
fn test_to_type_panics_on_layout_mismatch() {
fn test_as_type_panics_on_layout_mismatch() {
let vec = Vec::<u32>::new();
let mut erased = TypeErasedVec::new(vec);
let _ = erased.to_type::<u64>();
let _ = erased.as_type::<u64>();
}
#[test]
@@ -238,18 +238,18 @@ fn test_into_vec_panics_on_layout_mismatch() {
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "Calling `to_type_unchecked` with an incompatible layout is UB!")]
fn test_to_type_unchecked_panics_on_layout_mismatch_in_debug() {
#[should_panic(expected = "Calling `as_type_unchecked` with an incompatible layout is UB!")]
fn test_as_type_unchecked_panics_on_layout_mismatch_in_debug() {
let vec = Vec::<u32>::new();
let mut erased = TypeErasedVec::new(vec);
unsafe {
let _ = erased.to_type_unchecked::<u64>();
let _ = erased.as_type_unchecked::<u64>();
}
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "Calling `to_type_unchecked` with an incompatible layout is UB!")]
#[should_panic(expected = "Calling `as_type_unchecked` with an incompatible layout is UB!")]
fn test_into_vec_unchecked_panics_on_layout_mismatch_in_debug() {
let vec = Vec::<u32>::new();
let erased = TypeErasedVec::new(vec);