list_any/
vec.rs

1/* SPDX-License-Identifier: (Apache-2.0 OR MIT OR Zlib) */
2/* Copyright © 2021 Violet Leonard */
3
4#![allow(clippy::module_name_repetitions)]
5
6use core::{
7    any::{Any, TypeId},
8    marker::PhantomData,
9    mem,
10    ops::{Deref, DerefMut},
11    slice,
12};
13
14use alloc::vec::Vec;
15
16use super::{
17    AnyBound, DeferredValue, HasMetadata, Metadata, OpaqueValue, SliceAny,
18    SliceAnyMut,
19};
20
21/// # Safety
22/// Must be called with pointers formerly obtained from a Vec<T> that was
23/// not already dropped
24pub(crate) unsafe fn drop<T>(ptr: *mut (), len: usize, cap: usize) {
25    Vec::<T>::from_raw_parts(ptr.cast(), len, cap);
26}
27
28/// A type-erased [`Vec`](alloc::vec::Vec).
29///
30/// Semantically `Vec<dyn Any>`.
31///
32/// # Examples
33/// ```
34/// use list_any::VecAny;
35/// let data: Vec<u8> = b"hello".to_vec();
36/// let vec_any: VecAny = VecAny::from(data);
37/// let data_returned = vec_any.downcast::<u8>().unwrap();
38/// assert_eq!(data_returned, b"hello");
39/// ```
40#[derive(Debug)]
41pub struct VecAny<B: ?Sized = dyn Any + Send + Sync> {
42    ptr: *mut (),
43    meta: &'static Metadata,
44    len: usize,
45    cap: usize,
46    _marker: PhantomData<B>,
47}
48
49unsafe impl<B: ?Sized + Send> Send for VecAny<B> {}
50unsafe impl<B: ?Sized + Sync> Sync for VecAny<B> {}
51
52impl<B: ?Sized, T: AnyBound<B>> From<Vec<T>> for VecAny<B> {
53    fn from(vec: Vec<T>) -> Self {
54        let mut vec = mem::ManuallyDrop::new(vec);
55        let ptr = vec.as_mut_ptr().cast();
56        let meta = T::META;
57        let len = vec.len();
58        let cap = vec.capacity();
59        Self {
60            ptr,
61            meta,
62            len,
63            cap,
64            _marker: PhantomData,
65        }
66    }
67}
68
69impl<B: ?Sized> Drop for VecAny<B> {
70    fn drop(&mut self) {
71        unsafe {
72            (self.meta.drop)(self.ptr, self.len, self.cap);
73        }
74    }
75}
76
77impl VecAny {
78    /// Create a new, empty, [`VecAny`] for which downcasting will always
79    /// return `None`.
80    #[must_use]
81    pub fn opaque() -> Self {
82        Self::new::<OpaqueValue>()
83    }
84
85    /// Create a new, empty, [`VecAny`] with a internal type deferred until
86    /// the first mutable downcast.  Note that, until this type is otherwise
87    /// downcast, [`downcast_slice`](Self::downcast_slice) will always succeed.
88    ///
89    /// ```
90    /// use list_any::VecAny;
91    /// let mut v = VecAny::deferred();
92    /// assert_eq!(v.downcast_slice::<f64>(), Some(&[][..]));
93    /// assert_eq!(v.downcast_slice_mut::<u32>(), Some(&mut [][..]));
94    /// assert_eq!(v.downcast_slice::<f64>(), None);
95    /// ```
96    #[must_use]
97    pub fn deferred() -> Self {
98        Self::new::<DeferredValue>()
99    }
100}
101
102impl<B: ?Sized> VecAny<B> {
103    /// Create a new, empty, [`VecAny`] with a given internal type.
104    #[must_use]
105    pub fn new<T: AnyBound<B>>() -> Self {
106        Self::from(Vec::<T>::new())
107    }
108
109    /// Returns the number of elements in the vector.
110    #[must_use]
111    pub fn len(&self) -> usize {
112        self.len
113    }
114
115    /// Returns the number of elements the vector can hold without
116    /// reallocating.
117    #[must_use]
118    #[deprecated(
119        since = "0.2.1",
120        note = "method name was misspelled, use the correct spelling instead"
121    )]
122    pub fn capcaity(&self) -> usize {
123        self.cap
124    }
125
126    /// Returns the number of elements the vector can hold without
127    /// reallocating.
128    #[must_use]
129    pub fn capacity(&self) -> usize {
130        self.cap
131    }
132
133    /// Returns `true` if the vector contains no elements.
134    #[must_use]
135    pub fn is_empty(&self) -> bool {
136        self.len == 0
137    }
138
139    /// Returns the `TypeId` of the elements contained within the vector.
140    /// ```
141    /// use core::any::TypeId;
142    /// use list_any::VecAny;
143    /// let data: Vec<u8> = b"hello".to_vec();
144    /// let vec_any: VecAny = VecAny::from(data);
145    /// assert_eq!(vec_any.type_id_of_element(), TypeId::of::<u8>());
146    /// ```
147    #[must_use]
148    pub fn type_id_of_element(&self) -> TypeId {
149        (self.meta.type_id)()
150    }
151
152    /// Returns a borrow of this [`VecAny`] as a [`SliceAny`].
153    #[must_use]
154    pub fn as_slice_any(&self) -> SliceAny<'_> {
155        SliceAny {
156            ptr: self.ptr,
157            meta: self.meta,
158            len: self.len,
159            _marker: PhantomData,
160        }
161    }
162
163    /// Returns a mutable borrow of this [`VecAny`] as a [`SliceAnyMut`].
164    #[must_use]
165    pub fn as_slice_any_mut(&mut self) -> SliceAnyMut<'_> {
166        SliceAnyMut {
167            ptr: self.ptr,
168            meta: self.meta,
169            len: self.len,
170            _marker: PhantomData,
171        }
172    }
173
174    /// Attempts to downcast this [`VecAny`] to a concrete vector type.
175    ///
176    /// # Errors
177    ///
178    /// Returns self unchanged if the [`VecAny`] did not contain elements of
179    /// type `T`.
180    pub fn downcast<T: AnyBound<B>>(self) -> Result<Vec<T>, Self> {
181        if self.type_id_of_element() == TypeId::of::<T>() {
182            let this = mem::ManuallyDrop::new(self);
183            // SAFETY: just checked that we are pointing to the right type
184            // using private interface Metadata
185            Ok(unsafe {
186                Vec::from_raw_parts(this.ptr.cast(), this.len, this.cap)
187            })
188        } else if self.meta.is_deferred() {
189            // Optimization, Vec of DeferredValue never needs to be dropped
190            mem::forget(self);
191            Ok(Vec::new())
192        } else {
193            Err(self)
194        }
195    }
196
197    /// Returns some mutable guard over the original vector if the elements
198    /// are of type `T`, or `None` if they are not.
199    ///
200    /// Leaking this guard (through [`forget`](core::mem::forget) or similar)
201    /// is safe, however it will have the effect of leaking all of the
202    /// elements in the vector, and the source [`VecAny`] will be left empty.
203    #[must_use]
204    pub fn downcast_mut<T: AnyBound<B>>(
205        &mut self,
206    ) -> Option<VecAnyGuard<'_, T, B>> {
207        if self.type_id_of_element() == TypeId::of::<T>() {
208            // SAFETY: just checked that we are pointing to the right type
209            // using private interface Metadata
210            let vec = unsafe { self.swap_vec(Vec::new()) };
211            Some(VecAnyGuard { vec, origin: self })
212        } else if self.meta.is_deferred() {
213            // Optimization, Vec of DeferredValue never needs to be dropped
214            mem::forget(mem::replace(self, Self::new::<T>()));
215            // SAFETY: just inserted a vec of the right type
216            let vec = unsafe { self.swap_vec(Vec::new()) };
217            Some(VecAnyGuard { vec, origin: self })
218        } else {
219            None
220        }
221    }
222
223    /// Returns some reference to the contained vector as a slice if the
224    /// contained elements are of type `T`, or `None` if they are not.
225    #[must_use]
226    pub fn downcast_slice<T: AnyBound<B>>(&self) -> Option<&[T]> {
227        if self.type_id_of_element() == TypeId::of::<T>() {
228            // SAFETY: just checked that we are pointing to the right type
229            // using private interface Metadata
230            Some(unsafe { slice::from_raw_parts(self.ptr.cast(), self.len) })
231        } else if self.meta.is_deferred() {
232            Some(&[])
233        } else {
234            None
235        }
236    }
237
238    /// Returns some mutable reference to the contained vector as a slice if
239    /// the contained elements are of type `T`, or `None` if they are not.
240    #[must_use]
241    pub fn downcast_slice_mut<T: AnyBound<B>>(&mut self) -> Option<&mut [T]> {
242        if self.type_id_of_element() == TypeId::of::<T>() {
243            // SAFETY: just checked that we are pointing to the right type
244            // using private interface Metadata
245            Some(unsafe {
246                slice::from_raw_parts_mut(self.ptr.cast(), self.len)
247            })
248        } else if self.meta.is_deferred() {
249            // Optimization, Vec of DeferredValue never needs to be dropped
250            mem::forget(mem::replace(self, Self::new::<T>()));
251            // SAFETY: just inserted a vec of the right type
252            Some(unsafe {
253                slice::from_raw_parts_mut(self.ptr.cast(), self.len)
254            })
255        } else {
256            None
257        }
258    }
259
260    /// # Safety
261    /// This `VecAny` must be guaranteed to have the element type T
262    unsafe fn swap_vec<T: AnyBound<B>>(&mut self, new: Vec<T>) -> Vec<T> {
263        let mut new = mem::ManuallyDrop::new(new);
264        let mut ptr = new.as_mut_ptr().cast();
265        let mut len = new.len();
266        let mut cap = new.capacity();
267        mem::swap(&mut self.ptr, &mut ptr);
268        mem::swap(&mut self.len, &mut len);
269        mem::swap(&mut self.cap, &mut cap);
270        // SAFETY: these values came from us, and we always leave ourself in
271        // a valid state
272        Vec::from_raw_parts(ptr.cast(), len, cap)
273    }
274}
275
276/// A guard providing mutable access to a concretely typed vector, obtained
277/// with [`VecAny::downcast_mut`].
278///
279/// Leaking this guard (through [`forget`](core::mem::forget) or similar)
280/// is safe, however it will have the effect of leaking all of the
281/// elements in the vector, and the source [`VecAny`] will be left empty.
282#[derive(Debug)]
283pub struct VecAnyGuard<'a, T: AnyBound<B>, B: ?Sized = dyn Any + Send + Sync> {
284    vec: Vec<T>,
285    origin: &'a mut VecAny<B>,
286}
287
288impl<'a, T: AnyBound<B>, B: ?Sized> Deref for VecAnyGuard<'a, T, B> {
289    type Target = Vec<T>;
290
291    fn deref(&self) -> &Vec<T> {
292        &self.vec
293    }
294}
295
296impl<'a, T: AnyBound<B>, B: ?Sized> DerefMut for VecAnyGuard<'a, T, B> {
297    fn deref_mut(&mut self) -> &mut Vec<T> {
298        &mut self.vec
299    }
300}
301
302impl<'a, T: AnyBound<B>, B: ?Sized> Drop for VecAnyGuard<'a, T, B> {
303    fn drop(&mut self) {
304        // SAFETY: VecAnyGuard is only constructed with a valid T for
305        // the VecAny
306        unsafe {
307            self.origin.swap_vec(mem::take(&mut self.vec));
308        }
309    }
310}
311
312#[cfg(test)]
313mod tests {
314    use super::*;
315
316    #[test]
317    fn downcast_vec() {
318        use alloc::vec::Vec;
319
320        let data: Vec<u8> = b"hello".to_vec();
321        let mut vec_any: VecAny = VecAny::from(data);
322
323        assert_eq!(vec_any.type_id_of_element(), TypeId::of::<u8>());
324
325        assert!(vec_any.downcast_mut::<()>().is_none());
326        assert!(vec_any.downcast_mut::<u32>().is_none());
327        assert!(vec_any.downcast_mut::<u8>().is_some());
328
329        assert_eq!(vec_any.downcast_slice::<()>(), None);
330        assert_eq!(vec_any.downcast_slice::<u32>(), None);
331        assert_eq!(vec_any.downcast_slice::<u8>(), Some(&b"hello"[..]));
332
333        let vec_any = vec_any.downcast::<()>().unwrap_err();
334        let vec_any = vec_any.downcast::<u32>().unwrap_err();
335        let data = vec_any.downcast::<u8>().unwrap();
336        assert_eq!(data, b"hello".to_vec());
337    }
338
339    #[test]
340    fn deferred_vec() {
341        let mut v = VecAny::deferred();
342        assert_eq!(v.downcast_slice::<f64>(), Some(&[][..]));
343        assert_eq!(v.downcast_slice_mut::<u32>(), Some(&mut [][..]));
344        assert_eq!(v.downcast_slice::<f64>(), None);
345    }
346}