univec/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use std::any::{Any, TypeId};
4use std::fmt::{self, Debug, Formatter};
5use std::mem;
6
7pub use into_index::{At, AtMut, IntoIndex};
8
9/// A dynamic vector that can store elements of any single type.
10#[derive(Default)]
11pub struct UniVec(Option<Box<dyn UniVecOps>>);
12
13/// A macro to create a `UniVec` with elements.
14/// This macro wraps the `vec!` macro creating an `UniVec` instead.
15///
16/// # Examples
17///
18/// ```
19/// # use univec::univec;
20/// let univec = univec![42, 10];
21/// assert_eq!(univec.get::<i32>(0), Some(&42));
22/// assert_eq!(univec.get::<i32>(1), Some(&10));
23/// ```
24#[macro_export]
25macro_rules! univec {
26    () => ( $crate::UniVec::new() );
27    ($elem:expr; $n:expr) => ( $crate::UniVec::from(vec![$elem; $n]) );
28    ($($x:expr),+ $(,)?) => { $crate::UniVec::from(vec![$($x),+]) };
29}
30
31impl UniVec {
32    /// Creates a new empty `UniVec`. A new `UniVec` is empty and has no type associated to it,
33    /// the type becomes associated when adding the first data to it.
34    ///
35    /// # Example
36    ///
37    /// ```
38    /// # use univec::UniVec;
39    /// let univec = UniVec::new();
40    /// assert!(univec.is_empty());
41    /// ```
42    #[must_use]
43    pub const fn new() -> Self {
44        Self(None)
45    }
46
47    /// Creates a new empty `UniVec` with the specified capacity and type.
48    ///
49    /// # Arguments
50    ///
51    /// This function requires the 'turbofish' notation to associate a type to the `UniVec`.
52    ///
53    /// * `capacity` - The capacity to reserve.
54    ///
55    /// # Example
56    ///
57    /// ```
58    /// # use univec::UniVec;
59    /// let univec = UniVec::with_capacity::<i32>(10);
60    /// assert!(univec.capacity() >= 10);
61    /// ```
62    #[must_use]
63    pub fn with_capacity<T: 'static>(capacity: usize) -> Self {
64        Self(Some(Box::new(Vec::<T>::with_capacity(capacity))))
65    }
66
67    /// Try to get a reference to an element of type `T` by index.
68    ///
69    /// # Arguments
70    ///
71    /// * `index` - The index of the element to retrieve.
72    ///
73    /// # Returns
74    ///
75    /// Returns `Ok(Some(&T))` if the element is found, `Ok(None)` when the index is out of
76    /// range. This includes indices that can't be converted to `usize`.
77    ///
78    /// # Errors
79    ///
80    /// Returns `Err(TypeError)` when this `UniVec` does not store `T's`.
81    ///
82    /// # Example
83    ///
84    /// ```
85    /// # use univec::UniVec;
86    /// let mut univec = UniVec::new();
87    /// univec.push(42_i32);
88    ///
89    /// let element = univec.try_get::<i32>(0).unwrap();
90    ///
91    /// assert_eq!(element, Some(&42));
92    /// ```
93    pub fn try_get<T: 'static>(&self, index: impl IntoIndex) -> Result<Option<&T>, TypeError> {
94        if let Ok(index) = index.try_into_index() {
95            Ok(self.try_as_vec::<T>()?.and_then(|s| s.get(index)))
96        } else {
97            Ok(None)
98        }
99    }
100
101    /// Get a reference to an element of type `T` by index. This resembles the the `Vec::get`
102    /// method.
103    ///
104    /// # Arguments
105    ///
106    /// * `index` - The index of the element to retrieve.
107    ///
108    /// # Returns
109    ///
110    /// Returns `Some(&T)` it is found and `None` when the index is out of range.
111    /// This includes indices that can't be converted to `usize`.
112    ///
113    /// # Panics
114    ///
115    /// Panics if this `UniVec` does not store `T's`.
116    ///
117    /// # Example
118    ///
119    /// ```
120    /// # use univec::UniVec;
121    /// let mut univec = UniVec::new();
122    /// univec.push(42_i32);
123    ///
124    /// let element = univec.get::<i32>(0).unwrap();
125    ///
126    /// assert_eq!(element, &42);
127    /// ```
128    #[must_use]
129    pub fn get<T: 'static>(&self, index: impl IntoIndex) -> Option<&T> {
130        self.as_vec::<T>().get(index.try_into_index().ok()?)
131    }
132
133    /// Try to get a mutable reference to an element of type `T` by index.
134    ///
135    /// # Arguments
136    ///
137    /// * `index` - The index of the element to retrieve.
138    ///
139    /// # Returns
140    ///
141    /// Returns `Ok(Some(&mut T))` if the element is found, Ok(None) when the index is out of
142    /// range. This includes indices that can't be converted to `usize`.
143    ///
144    /// # Errors
145    ///
146    /// Returns `Err(TypeError)` when this `UniVec` does not store `T's`.
147    ///
148    /// # Example
149    ///
150    /// ```
151    /// # use univec::UniVec;
152    /// let mut univec = UniVec::new();
153    /// univec.push(42_i32);
154    ///
155    /// let mut element = univec.try_get_mut::<i32>(0).unwrap();
156    ///
157    /// if let Some(elem) = element {
158    ///     *elem += 10;
159    /// }
160    ///
161    /// assert_eq!(univec.try_get::<i32>(0).unwrap(), Some(&52));
162    /// ```
163    pub fn try_get_mut<T: 'static>(
164        &mut self,
165        index: impl IntoIndex,
166    ) -> Result<Option<&mut T>, TypeError> {
167        if let Ok(index) = index.try_into_index() {
168            Ok(self.try_as_vec_mut::<T>()?.and_then(|s| s.get_mut(index)))
169        } else {
170            Ok(None)
171        }
172    }
173
174    /// Get a mutable reference to an element of type `T` by index. Will associate `Self` with
175    /// a empty `Vec<T>` when the `UniVec` is not associated to a type.
176    ///
177    /// # Arguments
178    ///
179    /// * `index` - The index of the element to retrieve.
180    ///
181    /// # Returns
182    ///
183    /// Returns `Some(&mut T)` it is found and `None` when the index is out of range.
184    /// This includes indices that can't be converted to `usize`.
185    ///
186    /// # Panics
187    ///
188    /// Panics if this `UniVec` does not store `T's`.
189    ///
190    /// # Example
191    ///
192    /// ```
193    /// # use univec::UniVec;
194    /// let mut univec = UniVec::new();
195    /// univec.push(42_i32);
196    ///
197    /// let mut element = univec.get_mut::<i32>(0).unwrap();
198    ///
199    /// *element += 10;
200    ///
201    /// assert_eq!(univec.get::<i32>(0), Some(&52));
202    /// ```
203    #[must_use]
204    pub fn get_mut<T: 'static>(&mut self, index: impl IntoIndex) -> Option<&mut T> {
205        self.as_vec_mut::<T>().get_mut(index.try_into_index().ok()?)
206    }
207
208    /// Ensures that the `UniVec` stores `T's`. Possibly associate the requested type and
209    /// reserving the specified capacity.
210    ///
211    /// # Arguments
212    ///
213    /// * `capacity` - The capacity to reserve.
214    ///
215    /// # Returns
216    ///
217    /// Returns `Ok(())` when the `UniVec` was empty or `T` was already is associated.
218    /// The requested capacity is reserved then.
219    ///
220    /// # Errors
221    ///
222    /// Returns `Err(TypeError)` when this `UniVec` does not store `T's`.
223    ///
224    /// # Example
225    ///
226    /// ```
227    /// # use univec::UniVec;
228    /// let mut univec = UniVec::new();
229    ///
230    /// univec.ensure::<i32>(10).unwrap();
231    /// assert!(univec.capacity() >= 10);
232    /// assert_eq!(univec.associated_type(), Some(std::any::TypeId::of::<i32>()));
233    /// ```
234    pub fn ensure<T: 'static>(&mut self, capacity: usize) -> Result<(), TypeError> {
235        if self.0.is_none() {
236            self.0 = Some(Box::new(Vec::<T>::with_capacity(capacity)));
237        } else if !self.type_check::<T>() {
238            return Err(TypeError);
239        }
240
241        self.reserve(capacity);
242        Ok(())
243    }
244
245    /// Pushes a value of type `T` onto a `UniVec`.
246    ///
247    /// # Arguments
248    ///
249    /// * `value` - A `T` to push onto self.
250    ///
251    /// # Returns
252    ///
253    /// Returns `Ok(())` when the value was successfully pushed.
254    ///
255    /// # Errors
256    ///
257    /// Returns `Err(TypeErrorValue(value))` when this `UniVec` can not store `T's`.
258    ///
259    /// # Example
260    ///
261    /// ```
262    /// # use univec::UniVec;
263    /// let mut univec = UniVec::new();
264    /// univec.push(42_i32);
265    ///
266    /// let mut element = univec.get_mut::<i32>(0);
267    ///
268    /// if let Some(elem) = element {
269    ///     *elem += 10;
270    /// }
271    ///
272    /// assert_eq!(univec.get::<i32>(0), Some(&52));
273    /// ```
274    pub fn push<T: 'static>(&mut self, value: T) -> Result<(), TypeErrorValue<T>> {
275        if self.ensure::<T>(1).is_ok() {
276            self.as_vec_mut::<T>().push(value);
277            Ok(())
278        } else {
279            Err(TypeErrorValue(value))
280        }
281    }
282
283    /// Pops a dynamic typed value from a `UniVec`.
284    ///
285    /// # Returns
286    ///
287    /// Returns `Some(Box<dyn Any>)` if a value is successfully popped. `None` when the univec
288    /// was empty.
289    ///
290    /// # Example
291    ///
292    /// ```
293    /// # use univec::UniVec;
294    /// let mut univec = UniVec::new();
295    /// univec.push(42_i32);
296    ///
297    /// let popped = univec.pop_any().unwrap();
298    ///
299    /// assert_eq!(*popped.downcast::<i32>().unwrap(), 42);
300    /// ```
301    #[must_use]
302    pub fn pop_any(&mut self) -> Option<Box<dyn Any>> {
303        self.0.as_mut().and_then(|vec| vec.pop_box())
304    }
305
306    /// Pops a value of type `T` from a `UniVec`.
307    ///
308    /// # Returns
309    ///
310    /// Returns `Ok(Some(T))` with the value is successfully popped.
311    /// Returns `Ok(None)` when the univec is empty.
312    ///
313    /// # Errors
314    ///
315    /// Returns `Err(TypeError)` when the univec does not store `T's`.
316    ///
317    /// # Example
318    ///
319    /// ```
320    /// # use univec::UniVec;
321    /// let mut univec = UniVec::new();
322    /// univec.push(42_i32);
323    ///
324    /// let popped = univec.pop().unwrap();
325    ///
326    /// assert_eq!(popped, Some(42));
327    /// assert!(univec.is_empty());
328    /// ```
329    #[allow(clippy::missing_panics_doc)]
330    pub fn pop<T: 'static>(&mut self) -> Result<Option<T>, TypeError> {
331        Ok(self.try_as_vec_mut::<T>()?.and_then(Vec::pop))
332    }
333
334    /// Drops the last value from a `UniVec`. This is more efficient than the other `pop`
335    /// variants when the value is not required anymore.
336    ///
337    /// # Returns
338    ///
339    /// Returns `true` if a value is successfully dropped, otherwise returns `false`.
340    ///
341    /// # Example
342    ///
343    /// ```
344    /// # use univec::UniVec;
345    /// let mut univec = UniVec::new();
346    /// univec.push(42_i32);
347    ///
348    /// assert!(univec.drop_last());
349    /// assert!(univec.is_empty());
350    /// ```
351    pub fn drop_last(&mut self) -> bool {
352        self.0.as_mut().map_or(false, |vec| vec.drop_last())
353    }
354
355    /// Inserts a value of type `T` into the `UniVec` at the specified index.
356    ///
357    /// # Arguments
358    ///
359    /// * `index` - The index at which to insert the value.
360    /// * `value` - A reference to the value of type `T` to insert into the vector.
361    ///
362    /// # Errors
363    ///
364    /// Returns `Err(TypeErrorValue(value))` when this `UniVec` does not store `T's`.
365    ///
366    /// # Panics
367    ///
368    /// Panics if the index is out of bounds.
369    ///
370    /// # Example
371    ///
372    /// ```
373    /// # use univec::UniVec;
374    /// let mut univec = UniVec::new();
375    /// univec.push(42_i32);
376    ///
377    /// univec.insert(0, 10_i32).unwrap();
378    ///
379    /// assert_eq!(univec.get::<i32>(0), Some(&10));
380    /// assert_eq!(univec.get::<i32>(1), Some(&42));
381    /// ```
382    pub fn insert<T: 'static>(
383        &mut self,
384        index: impl IntoIndex,
385        value: T,
386    ) -> Result<(), TypeErrorValue<T>> {
387        if self.ensure::<T>(1).is_ok() {
388            // PLANNED: v2.0 report error instead panic
389            self.as_vec_mut::<T>().insert(index.into_index(), value);
390            Ok(())
391        } else {
392            Err(TypeErrorValue(value))
393        }
394    }
395
396    /// Removes a value of type `T` from an `UniVec` at the specified index.
397    ///
398    /// # Arguments
399    ///
400    /// * `index` - The index of the element to remove.
401    ///
402    /// # Panics
403    ///
404    /// Panics if index is out of bounds.
405    ///
406    /// # Returns
407    ///
408    /// Returns `Ok(T)` if a value is successfully removed.
409    ///
410    /// # Errors
411    ///
412    /// Returns `Err(TypeError)` when this `UniVec` does not store `T's`.
413    ///
414    /// # Example
415    ///
416    /// ```
417    /// # use univec::UniVec;
418    /// let mut univec = UniVec::new();
419    /// univec.push(42_i32);
420    ///
421    /// let removed = univec.remove::<i32>(0).unwrap();
422    ///
423    /// assert_eq!(removed, 42);
424    /// ```
425    pub fn remove<T: 'static>(&mut self, index: impl IntoIndex) -> Result<T, TypeError> {
426        Ok(self
427            .try_as_vec_mut::<T>()?
428            // PLANNED: v2.0 report error instead panic
429            .map(|v| v.remove(index.into_index()))
430            .expect("index out of bounds"))
431    }
432
433    /// Returns the length of a `UniVec`.
434    ///
435    /// # Returns
436    ///
437    /// Returns the length of the `UniVec`. A `UniVec` with no type associated is considered
438    /// empty with length 0.
439    ///
440    /// # Example
441    ///
442    /// ```
443    /// # use univec::UniVec;
444    /// let mut univec = UniVec::new();
445    /// assert_eq!(univec.len(), 0);
446    ///
447    /// univec.push(42_i32);
448    ///
449    /// assert_eq!(univec.len(), 1);
450    /// ```
451    #[must_use]
452    pub fn len(&self) -> usize {
453        self.0.as_ref().map_or(0, |vec| vec.len())
454    }
455
456    /// Returns whether a `UniVec` is empty.
457    ///
458    /// # Returns
459    ///
460    /// Returns `true` when the `UniVec` is empty, otherwise returns `false`.
461    ///
462    /// # Example
463    ///
464    /// ```
465    /// # use univec::UniVec;
466    /// let univec = UniVec::new();
467    ///
468    /// assert!(univec.is_empty());
469    /// ```
470    #[must_use]
471    #[inline]
472    pub fn is_empty(&self) -> bool {
473        self.0.as_ref().map_or(true, |vec| vec.len() == 0)
474    }
475
476    /// Returns the capacity of a `UniVec`.
477    ///
478    /// # Returns
479    ///
480    /// Returns the capacity of the `UniVec`. A `UniVec` with no type associated is considered
481    /// empty with capacity 0.
482    ///
483    /// # Example
484    ///
485    /// ```
486    /// # use univec::UniVec;
487    /// let mut univec = UniVec::new();
488    /// assert_eq!(univec.capacity(), 0);
489    ///
490    /// univec.push(42_i32);
491    ///
492    /// assert!(univec.capacity() >= 1);
493    /// ```
494    #[must_use]
495    pub fn capacity(&self) -> usize {
496        self.0.as_ref().map_or(0, |vec| vec.capacity())
497    }
498
499    /// Reserves capacity for at least additional more elements to be inserted in the given
500    /// `UniVec`. The collection may reserve more space to avoid frequent reallocations. Note
501    /// that `reserve()` will not reserve elements on a `UniVec` that has no type associated,
502    /// use `UniVec::with_capacity()` to initialize a `Univec` or `UniVec::ensure()` to
503    /// associate a type while reserving some elements.
504    ///
505    /// # Arguments
506    ///
507    /// * `additional` - The number of additional elements to reserve space for.
508    ///
509    /// # Example
510    ///
511    /// ```
512    /// # use univec::UniVec;
513    /// let mut univec = UniVec::new();
514    /// univec.push(42_i32);
515    ///
516    /// univec.reserve(10);
517    /// assert!(univec.capacity() >= 11);
518    /// ```
519    pub fn reserve(&mut self, additional: usize) {
520        if let Some(v) = self.0.as_mut() {
521            v.reserve(additional);
522        };
523    }
524
525    /// Replaces the element at the specified index with a new value.
526    ///
527    /// # Arguments
528    ///
529    /// * `index` - The index of the element to replace.
530    /// * `value` - The new value to replace the element with.
531    ///
532    /// # Panics
533    ///
534    /// Panics if index is out of bounds.
535    ///
536    /// # Returns
537    ///
538    /// Returns `Ok(T)` with the old value if a value is successfully replaced.
539    ///
540    /// # Errors
541    ///
542    /// Returns `Err(TypeErrorValue(value))` when this `UniVec` does not store `T's`.
543    ///
544    /// # Panics
545    ///
546    /// Panics if index is out of bounds.
547    ///
548    /// # Example
549    ///
550    /// ```
551    /// # use univec::UniVec;
552    /// let mut univec = UniVec::new();
553    /// univec.push(42_i32);
554    ///
555    /// let removed = univec.replace(0, 10_i32).unwrap();
556    ///
557    /// assert_eq!(removed, 42);
558    /// assert_eq!(univec.get::<i32>(0), Some(&10));
559    /// ```
560    pub fn replace<T: 'static>(
561        &mut self,
562        index: impl IntoIndex,
563        value: T,
564    ) -> Result<T, TypeErrorValue<T>> {
565        if self.type_check::<T>() {
566            Ok(mem::replace(
567                // PLANNED: v2.0 report error instead panic
568                self.get_mut::<T>(index.into_index())
569                    .expect("index out of bounds"),
570                value,
571            ))
572        } else {
573            Err(TypeErrorValue(value))
574        }
575    }
576
577    /// Tries to sets the last element of an `UniVec` to a new value. When the `UniVec` is
578    /// empty or not associated to a type, an initial value is pushed.
579    ///
580    /// # Arguments
581    ///
582    /// * `value` - the new value to replace the last element with.
583    ///
584    /// # Returns
585    ///
586    /// Returns `Ok(Some(T))` with the old last element or `Ok(None)` when the univec was
587    /// empty.
588    ///
589    /// # Errors
590    ///
591    /// Returns `Err(TypeErrorValue(value))` when this `UniVec` does not store `T's`.
592    ///
593    /// # Example
594    ///
595    /// ```
596    /// # use univec::UniVec;
597    /// let mut univec = UniVec::new();
598    ///
599    /// univec.try_set_last(10_i32).unwrap();
600    /// assert_eq!(univec.get::<i32>(0), Some(&10));
601    ///
602    /// univec.try_set_last(20_i32).unwrap();
603    /// assert_eq!(univec.get::<i32>(0), Some(&20));
604    /// ```
605    pub fn try_set_last<T: 'static>(&mut self, value: T) -> Result<Option<T>, TypeErrorValue<T>> {
606        Ok(if self.is_empty() {
607            self.push(value)?;
608            None
609        } else {
610            Some(self.replace(self.len() - 1, value)?)
611        })
612    }
613
614    /// Sets the last element of an `UniVec` to a new value. When the `UniVec` is
615    /// empty or not associated to a type, an initial value is pushed.
616    ///
617    /// # Arguments
618    ///
619    /// * `value` - The new value to replace the last element with.
620    ///
621    /// # Returns
622    ///
623    /// Returns `Some(T)` with the old last element or `None` when the univec was empty.
624    ///
625    /// # Panics
626    ///
627    /// Panics if this `UniVec` does not store `T's`.
628    ///
629    /// # Example
630    ///
631    /// ```
632    /// # use univec::UniVec;
633    /// let mut univec = UniVec::new();
634    ///
635    /// univec.set_last(10_i32);
636    /// assert_eq!(univec.get::<i32>(0), Some(&10));
637    ///
638    /// univec.set_last(20_i32);
639    /// assert_eq!(univec.get::<i32>(0), Some(&20));
640    /// ```
641    pub fn set_last<T: 'static>(&mut self, value: T) -> Option<T> {
642        self.try_set_last(value)
643            .unwrap_or_else(|_| panic!("This UniVec does not store the requested type"))
644    }
645
646    /// Checks whenever this `UniVec` is capable of storing `T`.
647    #[inline]
648    fn type_check<T: 'static>(&self) -> bool {
649        self.0
650            .as_ref()
651            .map_or(true, |vec| vec.inner_type_id() == TypeId::of::<T>())
652    }
653
654    /// Returns an `Option<TypeId>` the type is associated to a `UniVec`.
655    ///
656    /// # Returns
657    ///
658    /// Returns `Some(TypeId)` if a type is associated to this `UniVec`, otherwise returns `None`.
659    ///
660    /// # Example
661    ///
662    /// ```
663    /// # use univec::UniVec;
664    /// let mut univec = UniVec::new();
665    ///
666    /// assert_eq!(univec.associated_type(), None);
667    ///
668    /// univec.push(42_i32);
669    ///
670    /// assert_eq!(univec.associated_type(), Some(std::any::TypeId::of::<i32>()));
671    /// ```
672    #[must_use]
673    pub fn associated_type(&self) -> Option<TypeId> {
674        self.0.as_ref().map(|vec| vec.inner_type_id())
675    }
676
677    /// Returns the name of the type is associated to a `UniVec`.
678    ///
679    /// # Returns
680    ///
681    /// Returns `Some('static str)` if a type is associated to this `UniVec`, otherwise returns `None`.
682    ///
683    /// # Example
684    ///
685    /// ```
686    /// # use univec::UniVec;
687    /// let mut univec = UniVec::new();
688    ///
689    /// assert_eq!(univec.associated_type_name(), None);
690    ///
691    /// univec.push(42_i32);
692    ///
693    /// assert_eq!(univec.associated_type_name(), Some("i32"));
694    /// ```
695    #[must_use]
696    pub fn associated_type_name(&self) -> Option<&'static str> {
697        self.0.as_ref().map(|vec| vec.inner_type_name())
698    }
699
700    /// Takes the underlying original `Vec<T>` out of the `UniVec` and returns it.
701    /// `self` is left non associated and can be used to store a different type.
702    ///
703    /// # Returns
704    ///
705    /// Returns `Ok(Some(Vec<T>))` when the underlying vector is successfully taken.
706    /// Returns `Ok(None)` when `self` had no type associated.
707    ///
708    /// # Errors
709    ///
710    /// Returns `Err(TypeError)` when the `UniVec` does not store `T's`.
711    /// The `UniVec` is left unchanged then.
712    ///
713    /// # Example
714    ///
715    /// ```
716    /// # use univec::UniVec;
717    /// let mut univec = UniVec::new();
718    ///
719    /// univec.push(42_i32);
720    ///
721    /// let vec = univec.take::<i32>().unwrap().unwrap();
722    ///
723    /// assert_eq!(vec, vec![42]);
724    /// ```
725    pub fn take<T: 'static>(&mut self) -> Result<Option<Vec<T>>, TypeError> {
726        if self.is_empty() {
727            Ok(None)
728        } else if self.type_check::<T>() {
729            // SAFETY: We just checked the type_id and that the UniVec is not empty
730            unsafe {
731                let vec = self.0.take().unwrap_unchecked();
732                // PLANNED: use Box::into_inner() once stable or trait downcasting when available.
733                #[allow(clippy::cast_ptr_alignment)]
734                Ok(Some(*Box::from_raw(Box::into_raw(vec).cast::<Vec<T>>())))
735            }
736        } else {
737            Err(TypeError)
738        }
739    }
740
741    /// Returns the underlying original `Vec<T>` of a `UniVec`. Consumes the `UniVec`.
742    ///
743    /// # Returns
744    ///
745    /// Returns `Ok(Some(Vec<T>))` if the underlying vector was successfully taken.
746    /// Returns `Ok(None)` when the `UniVec` was empty.
747    ///
748    /// # Errors
749    ///
750    /// Returns `Err(TypeErrorIntoInner(self))` when the `UniVec` does not store `T's`.
751    ///
752    /// # Example
753    ///
754    /// ```
755    /// # use univec::UniVec;
756    /// let mut univec = UniVec::new();
757    ///
758    /// univec.push(42_i32);
759    ///
760    /// let vec = univec.into_inner::<i32>().unwrap().unwrap();
761    ///
762    /// assert_eq!(vec, vec![42]);
763    /// ```
764    pub fn into_inner<T: 'static>(mut self) -> Result<Option<Vec<T>>, TypeErrorIntoInner> {
765        if self.is_empty() {
766            Ok(None)
767        } else if self.type_check::<T>() {
768            // SAFETY: We just checked the type_id and that the UniVec is not empty
769            unsafe {
770                let vec = self.0.take().unwrap_unchecked();
771                // PLANNED: use Box::into_inner() once stable or trait downcasting when available.
772                #[allow(clippy::cast_ptr_alignment)]
773                Ok(Some(*Box::from_raw(Box::into_raw(vec).cast::<Vec<T>>())))
774            }
775        } else {
776            Err(TypeErrorIntoInner(self))
777        }
778    }
779
780    /// Try to get a reference to the underlying original `Vec<T>` of a `UniVec`.
781    ///
782    /// # Returns
783    ///
784    /// Returns `Ok(Some(&Vec<T>))` when the underlying `Vec<T>` is available.
785    /// Returns `Ok(None)` when the `UniVec` is not associated with any type.
786    ///
787    /// # Errors
788    ///
789    /// Returns `Err(TypeError)` when the `UniVec` does not store `T's`.
790    ///
791    /// # Example
792    ///
793    /// ```
794    /// # use univec::UniVec;
795    /// let mut univec = UniVec::new();
796    ///
797    /// univec.push(42_i32);
798    ///
799    /// let vec = univec.try_as_vec::<i32>().unwrap().unwrap();
800    ///
801    /// assert_eq!(*vec, vec![42]);
802    /// ```
803    pub fn try_as_vec<T: 'static>(&self) -> Result<Option<&Vec<T>>, TypeError> {
804        self.0
805            .as_ref()
806            .map(|b| b.as_any().downcast_ref::<Vec<T>>().ok_or(TypeError))
807            .transpose()
808    }
809
810    /// Get a reference to the underlying original `Vec<T>` of a `UniVec`.
811    ///
812    /// # Panics
813    ///
814    /// Panics if the `UniVec` does not store `T's` this includes the case when it has no
815    /// associated type.
816    ///
817    /// # Example
818    ///
819    /// ```
820    /// # use univec::UniVec;
821    /// let mut univec = UniVec::new();
822    ///
823    /// univec.push(42_i32);
824    ///
825    /// let vec = univec.as_vec::<i32>();
826    ///
827    /// assert_eq!(*vec, vec![42]);
828    /// ```
829    #[must_use]
830    pub fn as_vec<T: 'static>(&self) -> &Vec<T> {
831        self.0
832            .as_ref()
833            .expect("This Univec has no type associated")
834            .as_any()
835            .downcast_ref::<Vec<T>>()
836            .expect("This UniVec does not store the requested type")
837    }
838
839    // PLANNED: when stable
840    // unsafe fn as_vec_unchecked<T: 'static>(&mut self) -> &mut Vec<T> {
841    //      self.0
842    //         .as_ref()
843    //         .unwrap_unchecked()
844    //         .as_any()
845    //         .downcast_unchecked::<Vec<T>>()
846    // }
847
848    /// Try to get a mutable reference to the underlying original `Vec<T>` of a `UniVec`.
849    ///
850    /// # Returns
851    ///
852    /// Returns `Ok(Some(&mut Vec<T>))` if the underlying `Vec<T>` is available.
853    /// Returns `Ok(None)` when the `UniVec` is not associated to a type.
854    ///
855    /// # Errors
856    ///
857    /// Returns `Err(TypeError)` when the `UniVec` does not store `T's`.
858    ///
859    /// # Example
860    ///
861    /// ```
862    /// # use univec::UniVec;
863    /// let mut univec = UniVec::new();
864    ///
865    /// univec.push(42_i32);
866    ///
867    /// let vec = univec.try_as_vec_mut::<i32>().unwrap().unwrap();
868    ///
869    /// vec.push(10);
870    ///
871    /// assert_eq!(*vec, vec![42, 10]);
872    /// ```
873    pub fn try_as_vec_mut<T: 'static>(&mut self) -> Result<Option<&mut Vec<T>>, TypeError> {
874        self.0
875            .as_mut()
876            .map(|b| b.as_any_mut().downcast_mut::<Vec<T>>().ok_or(TypeError))
877            .transpose()
878    }
879
880    /// Get a mutable reference to the underlying original `Vec<T>` of a `UniVec`. Will
881    /// associate `Self` with a empty `Vec<T>` when the `UniVec` is not associated to a type.
882    ///
883    /// # Panics
884    ///
885    /// Panics if the `UniVec` does not store `T's`.
886    ///
887    /// # Example
888    ///
889    /// ```
890    /// # use univec::UniVec;
891    /// let mut univec = UniVec::new();
892    ///
893    /// univec.push(42_i32);
894    ///
895    /// let vec = univec.as_vec_mut::<i32>();
896    ///
897    /// vec.push(10);
898    ///
899    /// assert_eq!(*vec, vec![42, 10]);
900    /// ```
901    #[must_use]
902    pub fn as_vec_mut<T: 'static>(&mut self) -> &mut Vec<T> {
903        let _ = self.ensure::<T>(0);
904        self.0
905            .as_mut()
906            .expect("This Univec has no type associated")
907            .as_any_mut()
908            .downcast_mut::<Vec<T>>()
909            .expect("This UniVec does not store the requested type")
910    }
911
912    // PLANNED: when stable
913    // unsafe fn vec_mut_unchecked<T: 'static>(&mut self) -> &mut Vec<T> {
914    //      self.0
915    //         .as_mut()
916    //         .unwrap_unchecked()
917    //         .as_any_mut()
918    //         .downcast_mut_unchecked::<Vec<T>>()
919    // }
920
921    /// Try to get a reference to a slice of underlying original `Vec<T>` of a `UniVec`.
922    ///
923    /// # Returns
924    ///
925    /// Returns `Ok(Some(&[T]))` if the underlying `Vec<T>` is available.
926    /// Returns `Ok(None)` when the `UniVec` is not associated to a type.
927    ///
928    /// # Errors
929    ///
930    /// Returns `Err(TypeError)` when the `UniVec` does not store `T's`.
931    ///
932    /// # Example
933    ///
934    /// ```
935    /// # use univec::UniVec;
936    /// let mut univec = UniVec::new();
937    ///
938    /// univec.push(42_i32);
939    ///
940    /// let slice = univec.try_as_slice::<i32>().unwrap().unwrap();
941    ///
942    /// assert_eq!(slice, &[42]);
943    /// ```
944    #[inline]
945    pub fn try_as_slice<T: 'static>(&self) -> Result<Option<&[T]>, TypeError> {
946        Ok(self.try_as_vec::<T>()?.map(Vec::as_slice))
947    }
948
949    /// Get a reference to a slice of underlying original `Vec<T>` of a `UniVec`.
950    ///
951    /// # Returns
952    ///
953    /// Returns `&[T]` if the underlying `Vec<T>` is available.
954    ///
955    /// # Panics
956    ///
957    /// Panics if the `UniVec` does not store `T's` or has no associated type.
958    ///
959    /// # Example
960    ///
961    /// ```
962    /// # use univec::UniVec;
963    /// let mut univec = UniVec::new();
964    ///
965    /// univec.push(42_i32);
966    ///
967    /// let slice = univec.as_slice::<i32>();
968    ///
969    /// assert_eq!(slice, &[42]);
970    /// ```
971    #[inline]
972    #[must_use]
973    pub fn as_slice<T: 'static>(&self) -> &[T] {
974        self.as_vec::<T>().as_slice()
975    }
976
977    /// Try to get a mutable reference to a slice of underlying original `Vec<T>` of a
978    /// `UniVec`.
979    ///
980    /// # Returns
981    ///
982    /// Returns `Ok(Some(&mut [T]))` if the underlying `Vec<T>` is available.
983    /// Returns `Ok(None)` when the `UniVec` is not associated to a type.
984    ///
985    /// # Errors
986    ///
987    /// Returns `Err(TypeError)` when the `UniVec` does not store `T's`.
988    ///
989    /// # Example
990    ///
991    /// ```
992    /// # use univec::UniVec;
993    /// let mut univec = UniVec::new();
994    ///
995    /// univec.push(42_i32);
996    ///
997    /// let slice = univec.try_as_mut_slice::<i32>().unwrap().unwrap();
998    ///
999    /// slice[0] = 10;
1000    ///
1001    /// assert_eq!(slice, &[10]);
1002    /// assert_eq!(univec.get::<i32>(0), Some(&10));
1003    /// ```
1004    #[inline]
1005    pub fn try_as_mut_slice<T: 'static>(&mut self) -> Result<Option<&mut [T]>, TypeError> {
1006        Ok(self.try_as_vec_mut::<T>()?.map(Vec::as_mut_slice))
1007    }
1008
1009    /// Get a mutable reference to a slice of underlying original `Vec<T>` of a `UniVec`.
1010    /// Will associate `Self` with a empty `Vec<T>` when the `UniVec` is not associated to a
1011    /// type.
1012    ///
1013    /// # Returns
1014    ///
1015    /// Returns the underlying `&mut [T]`.
1016    ///
1017    /// # Panics
1018    ///
1019    /// Panics if the `UniVec` does not store `T's`.
1020    ///
1021    /// # Example
1022    ///
1023    /// ```
1024    /// # use univec::UniVec;
1025    /// let mut univec = UniVec::new();
1026    ///
1027    /// univec.push(42_i32);
1028    ///
1029    /// let slice = univec.as_mut_slice::<i32>();
1030    ///
1031    /// slice[0] = 10;
1032    ///
1033    /// assert_eq!(slice, &[10]);
1034    /// assert_eq!(univec.get::<i32>(0), Some(&10));
1035    /// ```
1036    #[inline]
1037    #[must_use]
1038    pub fn as_mut_slice<T: 'static>(&mut self) -> &mut [T] {
1039        self.as_vec_mut::<T>().as_mut_slice()
1040    }
1041}
1042
1043// UniVec needs a custom Debug implementation to relax the requirement of T: Debug.
1044impl Debug for UniVec {
1045    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1046        match self.0 {
1047            Some(ref vec) => write!(f, "UniVec(Some(Vec<{}>))", vec.inner_type_name()),
1048            None => write!(f, "UniVec(None)"),
1049        }
1050    }
1051}
1052
1053// private trait
1054trait UniVecOps: Any {
1055    /// Pops a value from the `UniVec` as a boxed trait object.
1056    ///
1057    /// # Returns
1058    ///
1059    /// Returns `Some(Box<dyn Any>)` if a value is successfully popped, otherwise returns `None`.
1060    fn pop_box(&mut self) -> Option<Box<dyn Any>>;
1061
1062    /// Pops and drops a value from the univec.
1063    ///
1064    /// # Returns
1065    ///
1066    /// Returns `true` if a value is successfully popped, otherwise returns `false`.
1067    fn drop_last(&mut self) -> bool;
1068
1069    /// Returns the length of an `UniVec`.
1070    fn len(&self) -> usize;
1071
1072    /// Returns the capacity of an `UniVec`.
1073    fn capacity(&self) -> usize;
1074
1075    /// Reserve capacity for at least additional more elements to be inserted in the given.
1076    fn reserve(&mut self, additional: usize);
1077
1078    /// Returns the `TypeId` of the stored elements
1079    fn inner_type_id(&self) -> TypeId;
1080
1081    /// Returns the type name of the stored elements
1082    fn inner_type_name(&self) -> &'static str;
1083
1084    /// Coerces `&self` to `&dyn Any`.
1085    fn as_any(&self) -> &dyn Any;
1086
1087    /// Coerces `&mut self` to `&mut dyn Any`.
1088    fn as_any_mut(&mut self) -> &mut dyn Any;
1089}
1090
1091impl<T> UniVecOps for Vec<T>
1092where
1093    T: 'static,
1094{
1095    fn pop_box(&mut self) -> Option<Box<dyn Any>> {
1096        let value = self.pop()?;
1097        Some(Box::new(value))
1098    }
1099
1100    #[inline]
1101    fn drop_last(&mut self) -> bool {
1102        self.pop().is_some()
1103    }
1104
1105    #[inline]
1106    fn len(&self) -> usize {
1107        self.len()
1108    }
1109
1110    #[inline]
1111    fn capacity(&self) -> usize {
1112        self.capacity()
1113    }
1114
1115    #[inline]
1116    fn reserve(&mut self, additional: usize) {
1117        self.reserve(additional);
1118    }
1119
1120    #[inline]
1121    fn inner_type_id(&self) -> TypeId {
1122        TypeId::of::<T>()
1123    }
1124
1125    fn inner_type_name(&self) -> &'static str {
1126        std::any::type_name::<T>()
1127    }
1128
1129    #[inline]
1130    fn as_any(&self) -> &dyn Any {
1131        self
1132    }
1133
1134    #[inline]
1135    fn as_any_mut(&mut self) -> &mut dyn Any {
1136        self
1137    }
1138}
1139
1140impl<T> From<Vec<T>> for UniVec
1141where
1142    T: 'static,
1143{
1144    #[inline]
1145    fn from(vec: Vec<T>) -> Self {
1146        Self(Some(Box::new(vec)))
1147    }
1148}
1149
1150impl<T> AsRef<[T]> for UniVec
1151where
1152    T: 'static,
1153{
1154    #[inline]
1155    fn as_ref(&self) -> &[T] {
1156        self.as_slice()
1157    }
1158}
1159
1160impl<T> AsMut<[T]> for UniVec
1161where
1162    T: 'static,
1163{
1164    #[inline]
1165    fn as_mut(&mut self) -> &mut [T] {
1166        self.as_mut_slice()
1167    }
1168}
1169
1170/// Error that happens on a query when the requested type is not stored in the `UniVec`.
1171// PLANNED: v2.0 enum {TypeError, RangeError}
1172#[derive(thiserror::Error, Debug, PartialEq)]
1173#[error("This UniVec does not store the requested type")]
1174pub struct TypeError;
1175
1176/// When pushing/setting an element fails because of a type error, one gets the failed element back.
1177// PLANNED: v2.0 enum {TypeErrorValue<T>, RangeErrorValue<T>}
1178#[derive(thiserror::Error, PartialEq)]
1179#[error("This UniVec does not store the requested type")]
1180pub struct TypeErrorValue<T>(
1181    /// The element that failed to insert.
1182    pub T,
1183);
1184
1185// needs a custom debug implementation to relax the requirement of T: Debug.
1186impl<T> Debug for TypeErrorValue<T> {
1187    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1188        write!(f, "TypeErrorValue<{}>", std::any::type_name::<T>())
1189    }
1190}
1191
1192/// When `UniVec::into_inner()` fails because of a type error, one gets the failed `UniVec` back.
1193#[derive(thiserror::Error, Debug)]
1194#[error("This UniVec does not store the requested type")]
1195pub struct TypeErrorIntoInner(
1196    /// The `UniVec` that failed to convert into the inner `Vec<T>`.
1197    pub UniVec,
1198);
1199
1200#[cfg(test)]
1201mod tests {
1202    use super::*;
1203
1204    // test UniVec::type_check()
1205    #[test]
1206    fn test_type_check() {
1207        let mut univec = UniVec::new();
1208        assert!(univec.type_check::<i64>());
1209        univec.push(42_i32).unwrap();
1210        assert!(univec.type_check::<i32>());
1211        assert!(!univec.type_check::<i64>());
1212    }
1213}