Skip to main content

fallible_collections/
vec.rs

1//! Implement Fallible Vec
2use super::TryClone;
3use crate::TryReserveError;
4#[allow(unused_imports)]
5use alloc::alloc::{alloc, realloc, Layout};
6use alloc::vec::Vec;
7use core::convert::TryInto as _;
8
9#[cfg(feature = "unstable")]
10#[macro_export]
11/// macro trying to create a vec, return a
12/// Result<Vec<T>,TryReserveError>
13macro_rules! try_vec {
14   ($elem:expr; $n:expr) => (
15        $crate::vec::try_from_elem($elem, $n)
16    );
17    ($($x:expr),*) => (
18        match <alloc::boxed::Box<_> as $crate::boxed::FallibleBox<_>>::try_new([$($x),*]) {
19            Err(e) => Err(e),
20            Ok(b) => Ok(<[_]>::into_vec(b)),
21        }
22    );
23    ($($x:expr,)*) => ($crate::try_vec![$($x),*])
24}
25
26/// trait implementing all fallible methods on vec
27pub trait FallibleVec<T> {
28    /// see reserve
29    fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>;
30    /// see push
31    fn try_push(&mut self, elem: T) -> Result<(), TryReserveError>;
32    /// try push and give back ownership in case of error
33    fn try_push_give_back(&mut self, elem: T) -> Result<(), (T, TryReserveError)>;
34    /// see with capacity, (Self must be sized by the constraint of Result)
35    fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError>
36    where
37        Self: core::marker::Sized;
38    /// see insert
39    fn try_insert(&mut self, index: usize, element: T) -> Result<(), (T, TryReserveError)>;
40    /// see append
41    fn try_append(&mut self, other: &mut Self) -> Result<(), TryReserveError>;
42    /// see resize, only works when the `value` implements Copy, otherwise, look at try_resize_no_copy
43    fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
44    where
45        T: Copy + Clone;
46    fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
47    where
48        F: FnMut() -> T;
49    /// resize the vec by trying to clone the value repeatingly
50    fn try_resize_no_copy(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
51    where
52        T: TryClone;
53    /// see resize, only works when the `value` implements Copy, otherwise, look at try_extend_from_slice_no_copy
54    fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError>
55    where
56        T: Copy + Clone;
57    /// extend the vec by trying to clone the value in `other`
58    fn try_extend_from_slice_no_copy(&mut self, other: &[T]) -> Result<(), TryReserveError>
59    where
60        T: TryClone;
61}
62
63/// TryVec is a thin wrapper around alloc::vec::Vec to provide support for
64/// fallible allocation.
65///
66/// See the crate documentation for more.
67#[derive(PartialEq)]
68pub struct TryVec<T> {
69    inner: Vec<T>,
70}
71
72impl<T> Default for TryVec<T> {
73    #[inline(always)]
74    fn default() -> Self {
75        Self {
76            inner: Default::default(),
77        }
78    }
79}
80
81impl<T: core::fmt::Debug> core::fmt::Debug for TryVec<T> {
82    #[inline]
83    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
84        self.inner.fmt(f)
85    }
86}
87
88impl<T> TryVec<T> {
89    #[inline(always)]
90    pub fn new() -> Self {
91        Self { inner: Vec::new() }
92    }
93
94    #[inline]
95    pub fn with_capacity(capacity: usize) -> Result<Self, TryReserveError> {
96        Ok(Self {
97            inner: FallibleVec::try_with_capacity(capacity)?,
98        })
99    }
100
101    #[inline(always)]
102    pub fn append(&mut self, other: &mut Self) -> Result<(), TryReserveError> {
103        FallibleVec::try_append(&mut self.inner, &mut other.inner)
104    }
105
106    #[inline(always)]
107    pub fn as_mut_slice(&mut self) -> &mut [T] {
108        self
109    }
110
111    #[inline(always)]
112    pub fn as_slice(&self) -> &[T] {
113        self
114    }
115
116    #[inline(always)]
117    pub fn clear(&mut self) {
118        self.inner.clear()
119    }
120
121    #[cfg(test)]
122    pub fn into_inner(self) -> Vec<T> {
123        self.inner
124    }
125
126    #[inline(always)]
127    pub fn is_empty(&self) -> bool {
128        self.inner.is_empty()
129    }
130
131    #[inline(always)]
132    pub fn iter_mut(&mut self) -> IterMut<T> {
133        IterMut {
134            inner: self.inner.iter_mut(),
135        }
136    }
137
138    #[inline(always)]
139    pub fn iter(&self) -> Iter<T> {
140        Iter {
141            inner: self.inner.iter(),
142        }
143    }
144
145    #[inline(always)]
146    pub fn pop(&mut self) -> Option<T> {
147        self.inner.pop()
148    }
149
150    #[inline(always)]
151    pub fn push(&mut self, value: T) -> Result<(), TryReserveError> {
152        FallibleVec::try_push(&mut self.inner, value)
153    }
154
155    #[inline(always)]
156    pub fn reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
157        FallibleVec::try_reserve(&mut self.inner, additional)
158    }
159
160    #[inline(always)]
161    pub fn resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
162    where
163        F: FnMut() -> T,
164    {
165        FallibleVec::try_resize_with(&mut self.inner, new_len, f)
166    }
167}
168
169impl<T: TryClone> TryClone for TryVec<T> {
170    #[inline]
171    fn try_clone(&self) -> Result<Self, TryReserveError> {
172        self.as_slice().try_into()
173    }
174}
175
176impl<T: TryClone> TryVec<TryVec<T>> {
177    pub fn concat(&self) -> Result<TryVec<T>, TryReserveError> {
178        let size = self.iter().map(|v| v.inner.len()).sum();
179        let mut result = TryVec::with_capacity(size)?;
180        for v in self.iter() {
181            result.inner.try_extend_from_slice_no_copy(&v.inner)?;
182        }
183        Ok(result)
184    }
185}
186
187impl<T: TryClone> TryVec<T> {
188    #[inline(always)]
189    pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError> {
190        self.inner.try_extend_from_slice_no_copy(other)
191    }
192}
193
194impl<T> IntoIterator for TryVec<T> {
195    type Item = T;
196    type IntoIter = alloc::vec::IntoIter<T>;
197
198    #[inline(always)]
199    fn into_iter(self) -> Self::IntoIter {
200        self.inner.into_iter()
201    }
202}
203
204impl<'a, T> IntoIterator for &'a TryVec<T> {
205    type Item = &'a T;
206    type IntoIter = alloc::slice::Iter<'a, T>;
207
208    #[inline(always)]
209    fn into_iter(self) -> Self::IntoIter {
210        self.inner.iter()
211    }
212}
213
214#[cfg(feature = "std_io")]
215pub mod std_io {
216    use super::*;
217    use std::io::{self, Read, Take, Write};
218
219    pub trait TryRead {
220        fn try_read_to_end(&mut self, buf: &mut TryVec<u8>) -> io::Result<usize>;
221
222        #[inline]
223        fn read_into_try_vec(&mut self) -> io::Result<TryVec<u8>> {
224            let mut buf = TryVec::new();
225            self.try_read_to_end(&mut buf)?;
226            Ok(buf)
227        }
228    }
229
230    impl<T: Read> TryRead for Take<T> {
231        /// This function reserves the upper limit of what `src` can generate before
232        /// reading all bytes until EOF in this source, placing them into `buf`. If the
233        /// allocation is unsuccessful, or reading from the source generates an error
234        /// before reaching EOF, this will return an error. Otherwise, it will return
235        /// the number of bytes read.
236        ///
237        /// Since `Take::limit()` may return a value greater than the number of bytes
238        /// which can be read from the source, it's possible this function may fail
239        /// in the allocation phase even though allocating the number of bytes available
240        /// to read would have succeeded. In general, it is assumed that the callers
241        /// have accurate knowledge of the number of bytes of interest and have created
242        /// `src` accordingly.
243        #[inline]
244        fn try_read_to_end(&mut self, buf: &mut TryVec<u8>) -> io::Result<usize> {
245            try_read_up_to(self, self.limit(), buf)
246        }
247    }
248
249    /// Read up to `limit` bytes from `src`, placing them into `buf` and returning the
250    /// number of bytes read. Space for `limit` additional bytes is reserved in `buf`, so
251    /// this function will return an error if the allocation fails.
252    pub fn try_read_up_to<R: Read>(
253        src: &mut R,
254        limit: u64,
255        buf: &mut TryVec<u8>,
256    ) -> io::Result<usize> {
257        let additional = limit
258            .try_into()
259            .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
260        buf.reserve(additional)
261            .map_err(|_| io::Error::new(io::ErrorKind::Other, "reserve allocation failed"))?;
262        let bytes_read = src.take(limit).read_to_end(&mut buf.inner)?;
263        Ok(bytes_read)
264    }
265
266    impl Write for TryVec<u8> {
267        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
268            self.extend_from_slice(buf)
269                .map_err(|_| io::Error::new(io::ErrorKind::Other, "extend_from_slice failed"))?;
270            Ok(buf.len())
271        }
272
273        #[inline(always)]
274        fn flush(&mut self) -> io::Result<()> {
275            Ok(())
276        }
277    }
278
279    #[cfg(test)]
280    mod tests {
281        use super::*;
282
283        #[test]
284        fn try_read_to_end() {
285            let mut src = b"1234567890".take(5);
286            let mut buf = TryVec::new();
287            src.try_read_to_end(&mut buf).unwrap();
288            assert_eq!(buf.len(), 5);
289            assert_eq!(buf, b"12345".as_ref());
290        }
291
292        #[test]
293        fn read_into_try_vec() {
294            let mut src = b"1234567890".take(5);
295            let buf = src.read_into_try_vec().unwrap();
296            assert_eq!(buf.len(), 5);
297            assert_eq!(buf, b"12345".as_ref());
298        }
299
300        #[test]
301        fn read_into_try_vec_oom() {
302            let mut src = b"1234567890".take(core::usize::MAX.try_into().expect("usize < u64"));
303            assert!(src.read_into_try_vec().is_err());
304        }
305
306        #[test]
307        fn try_read_up_to() {
308            let src = b"1234567890";
309            let mut buf = TryVec::new();
310            super::try_read_up_to(&mut src.as_ref(), 5, &mut buf).unwrap();
311            assert_eq!(buf.len(), 5);
312            assert_eq!(buf, b"12345".as_ref());
313        }
314
315        #[test]
316        fn try_read_up_to_oom() {
317            let src = b"1234567890";
318            let mut buf = TryVec::new();
319            let limit = core::usize::MAX.try_into().expect("usize < u64");
320            let res = super::try_read_up_to(&mut src.as_ref(), limit, &mut buf);
321            assert!(res.is_err());
322        }
323    }
324}
325
326impl<T: PartialEq> PartialEq<Vec<T>> for TryVec<T> {
327    #[inline(always)]
328    fn eq(&self, other: &Vec<T>) -> bool {
329        self.inner.eq(other)
330    }
331}
332
333impl<'a, T: PartialEq> PartialEq<&'a [T]> for TryVec<T> {
334    #[inline(always)]
335    fn eq(&self, other: &&[T]) -> bool {
336        self.inner.eq(other)
337    }
338}
339
340impl PartialEq<&str> for TryVec<u8> {
341    #[inline]
342    fn eq(&self, other: &&str) -> bool {
343        self.as_slice() == other.as_bytes()
344    }
345}
346
347impl core::convert::AsRef<[u8]> for TryVec<u8> {
348    #[inline(always)]
349    fn as_ref(&self) -> &[u8] {
350        self.inner.as_ref()
351    }
352}
353
354impl<T> core::convert::From<Vec<T>> for TryVec<T> {
355    #[inline(always)]
356    fn from(value: Vec<T>) -> Self {
357        Self { inner: value }
358    }
359}
360
361impl<T: TryClone> core::convert::TryFrom<&[T]> for TryVec<T> {
362    type Error = TryReserveError;
363
364    #[inline]
365    fn try_from(value: &[T]) -> Result<Self, Self::Error> {
366        let mut v = Self::new();
367        v.inner.try_extend_from_slice_no_copy(value)?;
368        Ok(v)
369    }
370}
371
372impl core::convert::TryFrom<&str> for TryVec<u8> {
373    type Error = TryReserveError;
374
375    #[inline]
376    fn try_from(value: &str) -> Result<Self, Self::Error> {
377        let mut v = Self::new();
378        v.extend_from_slice(value.as_bytes())?;
379        Ok(v)
380    }
381}
382
383impl<T> core::ops::Deref for TryVec<T> {
384    type Target = [T];
385
386    #[inline(always)]
387    fn deref(&self) -> &[T] {
388        self.inner.deref()
389    }
390}
391
392impl<T> core::ops::DerefMut for TryVec<T> {
393    fn deref_mut(&mut self) -> &mut [T] {
394        self.inner.deref_mut()
395    }
396}
397
398pub struct Iter<'a, T> {
399    inner: alloc::slice::Iter<'a, T>,
400}
401
402impl<'a, T> Iterator for Iter<'a, T> {
403    type Item = &'a T;
404
405    #[inline(always)]
406    fn next(&mut self) -> Option<Self::Item> {
407        self.inner.next()
408    }
409
410    #[inline(always)]
411    fn size_hint(&self) -> (usize, Option<usize>) {
412        self.inner.size_hint()
413    }
414}
415
416pub struct IterMut<'a, T> {
417    inner: alloc::slice::IterMut<'a, T>,
418}
419
420impl<'a, T> Iterator for IterMut<'a, T> {
421    type Item = &'a mut T;
422
423    #[inline(always)]
424    fn next(&mut self) -> Option<Self::Item> {
425        self.inner.next()
426    }
427
428    #[inline(always)]
429    fn size_hint(&self) -> (usize, Option<usize>) {
430        self.inner.size_hint()
431    }
432}
433
434fn needs_to_grow<T>(v: &Vec<T>, len: usize) -> bool {
435    v.len()
436        .checked_add(len)
437        .map_or(true, |needed| needed > v.capacity())
438}
439
440impl<T> FallibleVec<T> for Vec<T> {
441    #[inline(always)]
442    fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
443        self.try_reserve(additional)
444    }
445
446    #[inline]
447    fn try_push(&mut self, elem: T) -> Result<(), TryReserveError> {
448        if self.len() == self.capacity() {
449            self.try_reserve(1)?;
450        }
451        Ok(self.push(elem))
452    }
453
454    #[inline]
455    fn try_push_give_back(&mut self, elem: T) -> Result<(), (T, TryReserveError)> {
456        if self.len() == self.capacity() {
457            if let Err(e) = self.try_reserve(1) {
458                return Err((elem, e));
459            }
460        }
461        Ok(self.push(elem))
462    }
463
464    #[inline]
465    fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError>
466    where
467        Self: core::marker::Sized,
468    {
469        let mut n = Self::new();
470        FallibleVec::try_reserve(&mut n, capacity)?;
471        Ok(n)
472    }
473
474    #[inline]
475    fn try_insert(&mut self, index: usize, element: T) -> Result<(), (T, TryReserveError)> {
476        if self.len() == self.capacity() {
477            if let Err(e) = self.try_reserve(1) {
478                return Err((element, e));
479            }
480        }
481        Ok(self.insert(index, element))
482    }
483
484    #[inline]
485    fn try_append(&mut self, other: &mut Self) -> Result<(), TryReserveError> {
486        FallibleVec::try_reserve(self, other.len())?;
487        Ok(self.append(other))
488    }
489
490    fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
491    where
492        T: Copy + Clone,
493    {
494        let len = self.len();
495        if new_len > len {
496            FallibleVec::try_reserve(self, new_len - len)?;
497        }
498        Ok(self.resize(new_len, value))
499    }
500
501    fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
502    where
503        F: FnMut() -> T,
504    {
505        let len = self.len();
506        if new_len > len {
507            FallibleVec::try_reserve(self, new_len - len)?;
508        }
509        Ok(self.resize_with(new_len, f))
510    }
511
512    fn try_resize_no_copy(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
513    where
514        T: TryClone,
515    {
516        let len = self.len();
517
518        if new_len > len {
519            self.try_extend_with(new_len - len, TryExtendElement(value))
520        } else {
521            Ok(Truncate::truncate(self, new_len))
522        }
523    }
524
525    #[inline]
526    fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError>
527    where
528        T: Clone,
529    {
530        if needs_to_grow(self, other.len()) {
531            self.try_reserve(other.len())?;
532        }
533        Ok(self.extend_from_slice(other))
534    }
535
536    fn try_extend_from_slice_no_copy(&mut self, other: &[T]) -> Result<(), TryReserveError>
537    where
538        T: TryClone,
539    {
540        if needs_to_grow(self, other.len()) {
541            self.try_reserve(other.len())?;
542        }
543        let mut len = self.len();
544        let mut iterator = other.iter();
545        while let Some(element) = iterator.next() {
546            unsafe {
547                core::ptr::write(self.as_mut_ptr().add(len), element.try_clone()?);
548                // NB can't overflow since we would have had to alloc the address space
549                len += 1;
550                self.set_len(len);
551            }
552        }
553        Ok(())
554    }
555}
556
557trait ExtendWith<T> {
558    fn next(&mut self) -> Result<T, TryReserveError>;
559    fn last(self) -> T;
560}
561
562struct TryExtendElement<T: TryClone>(T);
563impl<T: TryClone> ExtendWith<T> for TryExtendElement<T> {
564    #[inline(always)]
565    fn next(&mut self) -> Result<T, TryReserveError> {
566        self.0.try_clone()
567    }
568    #[inline(always)]
569    fn last(self) -> T {
570        self.0
571    }
572}
573
574trait TryExtend<T> {
575    fn try_extend_with<E: ExtendWith<T>>(
576        &mut self,
577        n: usize,
578        value: E,
579    ) -> Result<(), TryReserveError>;
580}
581
582impl<T> TryExtend<T> for Vec<T> {
583    /// Extend the vector by `n` values, using the given generator.
584    fn try_extend_with<E: ExtendWith<T>>(
585        &mut self,
586        n: usize,
587        mut value: E,
588    ) -> Result<(), TryReserveError> {
589        if needs_to_grow(self, n) {
590            self.try_reserve(n)?;
591        }
592
593        unsafe {
594            let mut ptr = self.as_mut_ptr().add(self.len());
595
596            let mut local_len = self.len();
597            // Write all elements except the last one
598            for _ in 1..n {
599                core::ptr::write(ptr, value.next()?);
600                ptr = ptr.offset(1);
601                // Increment the length in every step in case next() panics
602                local_len += 1;
603                self.set_len(local_len);
604            }
605
606            if n > 0 {
607                // We can write the last element directly without cloning needlessly
608                core::ptr::write(ptr, value.last());
609                local_len += 1;
610                self.set_len(local_len);
611            }
612
613            // len set by scope guard
614        }
615        Ok(())
616    }
617}
618
619trait Truncate {
620    fn truncate(&mut self, len: usize);
621}
622
623impl<T> Truncate for Vec<T> {
624    fn truncate(&mut self, len: usize) {
625        let current_len = self.len();
626        unsafe {
627            let mut ptr = self.as_mut_ptr().add(current_len);
628            // Set the final length at the end, keeping in mind that
629            // dropping an element might panic. Works around a missed
630            // optimization, as seen in the following issue:
631            // https://github.com/rust-lang/rust/issues/51802
632            let mut local_len = self.len();
633
634            // drop any extra elements
635            for _ in len..current_len {
636                ptr = ptr.offset(-1);
637                core::ptr::drop_in_place(ptr);
638                local_len -= 1;
639                self.set_len(local_len);
640            }
641        }
642    }
643}
644
645/// try creating a vec from an `elem` cloned `n` times, see std::from_elem
646#[cfg(feature = "unstable")]
647pub fn try_from_elem<T: TryClone>(elem: T, n: usize) -> Result<Vec<T>, TryReserveError> {
648    <T as SpecFromElem>::try_from_elem(elem, n)
649}
650
651// Specialization trait used for Vec::from_elem
652#[cfg(feature = "unstable")]
653trait SpecFromElem: Sized {
654    fn try_from_elem(elem: Self, n: usize) -> Result<Vec<Self>, TryReserveError>;
655}
656
657#[cfg(feature = "unstable")]
658impl<T: TryClone> SpecFromElem for T {
659    default fn try_from_elem(elem: Self, n: usize) -> Result<Vec<T>, TryReserveError> {
660        let mut v = Vec::new();
661        v.try_resize_no_copy(n, elem)?;
662        Ok(v)
663    }
664}
665
666#[cfg(feature = "unstable")]
667impl SpecFromElem for u8 {
668    #[inline]
669    fn try_from_elem(elem: u8, n: usize) -> Result<Vec<u8>, TryReserveError> {
670        unsafe {
671            let mut v: Vec<u8> = FallibleVec::try_with_capacity(n)?;
672            core::ptr::write_bytes(v.as_mut_ptr(), elem, n);
673            v.set_len(n);
674            Ok(v)
675        }
676    }
677}
678
679impl<T: TryClone> TryClone for Vec<T> {
680    #[inline]
681    fn try_clone(&self) -> Result<Self, TryReserveError>
682    where
683        Self: core::marker::Sized,
684    {
685        let mut v = Vec::new();
686        v.try_extend_from_slice_no_copy(self)?;
687        Ok(v)
688    }
689}
690
691pub trait TryFromIterator<I>: Sized {
692    fn try_from_iterator<T: IntoIterator<Item = I>>(iterator: T) -> Result<Self, TryReserveError>;
693}
694
695impl<I> TryFromIterator<I> for Vec<I> {
696    fn try_from_iterator<T: IntoIterator<Item = I>>(iterator: T) -> Result<Self, TryReserveError>
697    where
698        T: IntoIterator<Item = I>,
699    {
700        let mut new = Self::new();
701        for i in iterator {
702            new.try_push(i)?;
703        }
704        Ok(new)
705    }
706}
707
708pub trait TryCollect<I> {
709    fn try_collect<C: TryFromIterator<I>>(self) -> Result<C, TryReserveError>;
710}
711
712impl<I, T> TryCollect<I> for T
713where
714    T: IntoIterator<Item = I>,
715{
716    #[inline(always)]
717    fn try_collect<C: TryFromIterator<I>>(self) -> Result<C, TryReserveError> {
718        C::try_from_iterator(self)
719    }
720}
721
722#[cfg(test)]
723mod tests {
724    use super::*;
725
726    #[test]
727    #[cfg(feature = "unstable")]
728    fn vec() {
729        // let v: Vec<u8> = from_elem(1, 10);
730        let v: Vec<Vec<u8>> = try_vec![try_vec![42; 10].unwrap(); 100].unwrap();
731        println!("{:?}", v);
732        let v2 = try_vec![0, 1, 2];
733        println!("{:?}", v2);
734        assert_eq!(2 + 2, 4);
735    }
736
737    #[test]
738    fn try_clone_vec() {
739        // let v: Vec<u8> = from_elem(1, 10);
740        let v = vec![42; 100];
741        assert_eq!(v.try_clone().unwrap(), v);
742    }
743
744    #[test]
745    fn try_clone_oom() {
746        let layout = Layout::new::<u8>();
747        let v = unsafe {
748            Vec::<u8>::from_raw_parts(
749                alloc(layout),
750                core::isize::MAX as usize,
751                core::isize::MAX as usize,
752            )
753        };
754        assert!(v.try_clone().is_err());
755    }
756
757    #[test]
758    fn tryvec_try_clone_oom() {
759        let layout = Layout::new::<u8>();
760        let inner = unsafe {
761            Vec::<u8>::from_raw_parts(
762                alloc(layout),
763                core::isize::MAX as usize,
764                core::isize::MAX as usize,
765            )
766        };
767        let tv = TryVec { inner };
768        assert!(tv.try_clone().is_err());
769    }
770
771    // #[test]
772    // fn try_out_of_mem() {
773    //     let v = try_vec![42_u8; 1000000000];
774    //     assert_eq!(v.try_clone().unwrap(), v);
775    // }
776
777    #[test]
778    fn oom() {
779        let mut vec: Vec<char> = Vec::new();
780        match FallibleVec::try_reserve(&mut vec, core::usize::MAX / std::mem::size_of::<char>()) {
781            Ok(_) => panic!("it should be OOM"),
782            _ => (),
783        }
784        match FallibleVec::try_reserve(&mut vec, core::usize::MAX) {
785            Ok(_) => panic!("it should be OOM"),
786            _ => (),
787        }
788    }
789
790    #[test]
791    fn tryvec_oom() {
792        let mut vec: TryVec<char> = TryVec::new();
793        match vec.reserve(core::usize::MAX / std::mem::size_of::<char>()) {
794            Ok(_) => panic!("it should be OOM"),
795            _ => (),
796        }
797        match vec.reserve(core::usize::MAX) {
798            Ok(_) => panic!("it should be OOM"),
799            _ => (),
800        }
801    }
802
803    #[test]
804    fn try_reserve() {
805        let mut vec: Vec<_> = vec![1];
806        let additional_room = vec.capacity() - vec.len();
807        let additional = additional_room + 1;
808        let old_cap = vec.capacity();
809        FallibleVec::try_reserve(&mut vec, additional).unwrap();
810        assert!(vec.capacity() > old_cap);
811    }
812
813    #[test]
814    fn tryvec_reserve() {
815        let mut vec: TryVec<_> = vec![1].into();
816        let old_cap = vec.inner.capacity();
817        let new_cap = old_cap + 1;
818        vec.reserve(new_cap).unwrap();
819        assert!(vec.inner.capacity() >= new_cap);
820    }
821
822    #[test]
823    fn try_reserve_idempotent() {
824        let mut vec: Vec<_> = vec![1];
825        let additional_room = vec.capacity() - vec.len();
826        let additional = additional_room + 1;
827        FallibleVec::try_reserve(&mut vec, additional).unwrap();
828        let cap_after_reserve = vec.capacity();
829        FallibleVec::try_reserve(&mut vec, additional).unwrap();
830        assert_eq!(vec.capacity(), cap_after_reserve);
831    }
832
833    #[test]
834    fn tryvec_reserve_idempotent() {
835        let mut vec: TryVec<_> = vec![1].into();
836        let old_cap = vec.inner.capacity();
837        let new_cap = old_cap + 1;
838        vec.reserve(new_cap).unwrap();
839        let cap_after_reserve = vec.inner.capacity();
840        vec.reserve(new_cap).unwrap();
841        assert_eq!(cap_after_reserve, vec.inner.capacity());
842    }
843
844    #[test]
845    fn capacity_overflow() {
846        let mut vec: Vec<_> = vec![1];
847        match FallibleVec::try_reserve(&mut vec, core::usize::MAX) {
848            Ok(_) => panic!("capacity calculation should overflow"),
849            _ => (),
850        }
851    }
852
853    #[test]
854    fn tryvec_capacity_overflow() {
855        let mut vec: TryVec<_> = vec![1].into();
856        match vec.reserve(core::usize::MAX) {
857            Ok(_) => panic!("capacity calculation should overflow"),
858            _ => (),
859        }
860    }
861
862    #[test]
863    fn extend_from_slice() {
864        let mut vec: Vec<u8> = b"foo".as_ref().into();
865        vec.shrink_to_fit();
866        vec.reserve(5);
867        assert_eq!(8, vec.capacity());
868        vec.try_extend_from_slice(b"bar").unwrap();
869        assert_eq!(vec, b"foobar".as_ref());
870        vec.try_extend_from_slice(b"1").unwrap();
871        assert_eq!(vec, b"foobar1".as_ref());
872        assert_eq!(8, vec.capacity());
873        vec.try_extend_from_slice(b"11").unwrap();
874        assert_eq!(16, vec.capacity());
875    }
876
877    #[test]
878    fn tryvec_extend_from_slice() {
879        let mut vec: TryVec<u8> = b"foo".as_ref().try_into().unwrap();
880        vec.extend_from_slice(b"bar").unwrap();
881        assert_eq!(vec, b"foobar".as_ref());
882    }
883
884    #[test]
885    fn try_reserve_zst() {
886        let mut vec: Vec<()> = Vec::new();
887        assert!(FallibleVec::try_reserve(&mut vec, core::usize::MAX).is_ok());
888    }
889}