#![allow(clippy::module_name_repetitions)]
use core::{
any::{Any, TypeId},
marker::PhantomData,
mem,
ops::{Deref, DerefMut},
slice,
};
use alloc::vec::Vec;
use super::{
AnyBound, DeferredValue, HasMetadata, Metadata, OpaqueValue, SliceAny,
SliceAnyMut,
};
pub(crate) unsafe fn drop<T>(ptr: *mut (), len: usize, cap: usize) {
Vec::<T>::from_raw_parts(ptr.cast(), len, cap);
}
#[derive(Debug)]
pub struct VecAny<B: ?Sized = dyn Any + Send + Sync> {
ptr: *mut (),
meta: &'static Metadata,
len: usize,
cap: usize,
_marker: PhantomData<B>,
}
unsafe impl<B: ?Sized + Send> Send for VecAny<B> {}
unsafe impl<B: ?Sized + Sync> Sync for VecAny<B> {}
impl<B: ?Sized, T: AnyBound<B>> From<Vec<T>> for VecAny<B> {
fn from(vec: Vec<T>) -> Self {
let mut vec = mem::ManuallyDrop::new(vec);
let ptr = vec.as_mut_ptr().cast();
let meta = T::META;
let len = vec.len();
let cap = vec.capacity();
Self {
ptr,
meta,
len,
cap,
_marker: PhantomData,
}
}
}
impl<B: ?Sized> Drop for VecAny<B> {
fn drop(&mut self) {
unsafe {
(self.meta.drop)(self.ptr, self.len, self.cap);
}
}
}
impl VecAny {
#[must_use]
pub fn opaque() -> Self {
Self::new::<OpaqueValue>()
}
#[must_use]
pub fn deferred() -> Self {
Self::new::<DeferredValue>()
}
}
impl<B: ?Sized> VecAny<B> {
#[must_use]
pub fn new<T: AnyBound<B>>() -> Self {
Self::from(Vec::<T>::new())
}
#[must_use]
pub fn len(&self) -> usize {
self.len
}
#[must_use]
#[deprecated(
since = "0.2.1",
note = "method name was misspelled, use the correct spelling instead"
)]
pub fn capcaity(&self) -> usize {
self.cap
}
#[must_use]
pub fn capacity(&self) -> usize {
self.cap
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[must_use]
pub fn type_id_of_element(&self) -> TypeId {
(self.meta.type_id)()
}
#[must_use]
pub fn as_slice_any(&self) -> SliceAny<'_> {
SliceAny {
ptr: self.ptr,
meta: self.meta,
len: self.len,
_marker: PhantomData,
}
}
#[must_use]
pub fn as_slice_any_mut(&mut self) -> SliceAnyMut<'_> {
SliceAnyMut {
ptr: self.ptr,
meta: self.meta,
len: self.len,
_marker: PhantomData,
}
}
pub fn downcast<T: AnyBound<B>>(self) -> Result<Vec<T>, Self> {
if self.type_id_of_element() == TypeId::of::<T>() {
let this = mem::ManuallyDrop::new(self);
Ok(unsafe {
Vec::from_raw_parts(this.ptr.cast(), this.len, this.cap)
})
} else if self.meta.is_deferred() {
mem::forget(self);
Ok(Vec::new())
} else {
Err(self)
}
}
#[must_use]
pub fn downcast_mut<T: AnyBound<B>>(
&mut self,
) -> Option<VecAnyGuard<'_, T, B>> {
if self.type_id_of_element() == TypeId::of::<T>() {
let vec = unsafe { self.swap_vec(Vec::new()) };
Some(VecAnyGuard { vec, origin: self })
} else if self.meta.is_deferred() {
mem::forget(mem::replace(self, Self::new::<T>()));
let vec = unsafe { self.swap_vec(Vec::new()) };
Some(VecAnyGuard { vec, origin: self })
} else {
None
}
}
#[must_use]
pub fn downcast_slice<T: AnyBound<B>>(&self) -> Option<&[T]> {
if self.type_id_of_element() == TypeId::of::<T>() {
Some(unsafe { slice::from_raw_parts(self.ptr.cast(), self.len) })
} else if self.meta.is_deferred() {
Some(&[])
} else {
None
}
}
#[must_use]
pub fn downcast_slice_mut<T: AnyBound<B>>(&mut self) -> Option<&mut [T]> {
if self.type_id_of_element() == TypeId::of::<T>() {
Some(unsafe {
slice::from_raw_parts_mut(self.ptr.cast(), self.len)
})
} else if self.meta.is_deferred() {
mem::forget(mem::replace(self, Self::new::<T>()));
Some(unsafe {
slice::from_raw_parts_mut(self.ptr.cast(), self.len)
})
} else {
None
}
}
unsafe fn swap_vec<T: AnyBound<B>>(&mut self, new: Vec<T>) -> Vec<T> {
let mut new = mem::ManuallyDrop::new(new);
let mut ptr = new.as_mut_ptr().cast();
let mut len = new.len();
let mut cap = new.capacity();
mem::swap(&mut self.ptr, &mut ptr);
mem::swap(&mut self.len, &mut len);
mem::swap(&mut self.cap, &mut cap);
Vec::from_raw_parts(ptr.cast(), len, cap)
}
}
#[derive(Debug)]
pub struct VecAnyGuard<'a, T: AnyBound<B>, B: ?Sized = dyn Any + Send + Sync> {
vec: Vec<T>,
origin: &'a mut VecAny<B>,
}
impl<'a, T: AnyBound<B>, B: ?Sized> Deref for VecAnyGuard<'a, T, B> {
type Target = Vec<T>;
fn deref(&self) -> &Vec<T> {
&self.vec
}
}
impl<'a, T: AnyBound<B>, B: ?Sized> DerefMut for VecAnyGuard<'a, T, B> {
fn deref_mut(&mut self) -> &mut Vec<T> {
&mut self.vec
}
}
impl<'a, T: AnyBound<B>, B: ?Sized> Drop for VecAnyGuard<'a, T, B> {
fn drop(&mut self) {
unsafe {
self.origin.swap_vec(mem::take(&mut self.vec));
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn downcast_vec() {
use alloc::vec::Vec;
let data: Vec<u8> = b"hello".to_vec();
let mut vec_any: VecAny = VecAny::from(data);
assert_eq!(vec_any.type_id_of_element(), TypeId::of::<u8>());
assert!(vec_any.downcast_mut::<()>().is_none());
assert!(vec_any.downcast_mut::<u32>().is_none());
assert!(vec_any.downcast_mut::<u8>().is_some());
assert_eq!(vec_any.downcast_slice::<()>(), None);
assert_eq!(vec_any.downcast_slice::<u32>(), None);
assert_eq!(vec_any.downcast_slice::<u8>(), Some(&b"hello"[..]));
let vec_any = vec_any.downcast::<()>().unwrap_err();
let vec_any = vec_any.downcast::<u32>().unwrap_err();
let data = vec_any.downcast::<u8>().unwrap();
assert_eq!(data, b"hello".to_vec());
}
#[test]
fn deferred_vec() {
let mut v = VecAny::deferred();
assert_eq!(v.downcast_slice::<f64>(), Some(&[][..]));
assert_eq!(v.downcast_slice_mut::<u32>(), Some(&mut [][..]));
assert_eq!(v.downcast_slice::<f64>(), None);
}
}