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}