From 488efd0b3e8ee7f41606403b3986020e45c7b36c Mon Sep 17 00:00:00 2001 From: Paul Kernfeld Date: Tue, 12 May 2020 12:04:09 -0400 Subject: [PATCH 1/2] impl TryFrom<&[A::Item]> for ArrayVec For issue #106 --- src/lib.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 848c5a5..62cbed0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -708,6 +708,30 @@ impl From for ArrayVec { } +/// Try to create an `ArrayVec` from a slice. This will return an error if the slice was too big to +/// fit. +/// +/// ``` +/// use arrayvec::ArrayVec; +/// use std::convert::TryInto as _; +/// +/// let mut array: ArrayVec<[_; 4]> = (&[1, 2, 3] as &[_]).try_into().unwrap(); +/// assert_eq!(array.len(), 3); +/// assert_eq!(array.capacity(), 4); +/// ``` +impl std::convert::TryFrom<&[A::Item]> for ArrayVec + where + A::Item: Copy, +{ + type Error = CapacityError; + + fn try_from(slice: &[A::Item]) -> Result { + let mut array = Self::new(); + array.try_extend_from_slice(slice).map(|()| array) + } +} + + /// Iterate the `ArrayVec` with references to each element. /// /// ``` From 675e992741185ac897010a73ec54a9483da6e919 Mon Sep 17 00:00:00 2001 From: Paul Kernfeld Date: Tue, 12 May 2020 14:57:38 -0400 Subject: [PATCH 2/2] allow items that implement Clone --- src/lib.rs | 13 +++++++++---- tests/tests.rs | 9 +++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 62cbed0..0268334 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -715,19 +715,24 @@ impl From for ArrayVec { /// use arrayvec::ArrayVec; /// use std::convert::TryInto as _; /// -/// let mut array: ArrayVec<[_; 4]> = (&[1, 2, 3] as &[_]).try_into().unwrap(); +/// let array: ArrayVec<[_; 4]> = (&[1, 2, 3] as &[_]).try_into().unwrap(); /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 4); /// ``` impl std::convert::TryFrom<&[A::Item]> for ArrayVec where - A::Item: Copy, + A::Item: Clone, { type Error = CapacityError; fn try_from(slice: &[A::Item]) -> Result { - let mut array = Self::new(); - array.try_extend_from_slice(slice).map(|()| array) + if A::CAPACITY < slice.len() { + Err(CapacityError::new(())) + } else { + let mut array = Self::new(); + array.extend(slice.iter().cloned()); + Ok(array) + } } } diff --git a/tests/tests.rs b/tests/tests.rs index 1cf3aad..c7ebcd0 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -65,6 +65,15 @@ fn test_extend_from_slice_error() { assert_matches!(res, Err(_)); } +#[test] +fn test_try_from_slice_error() { + use arrayvec::ArrayVec; + use std::convert::TryInto as _; + + let res: Result, _> = (&[1, 2, 3] as &[_]).try_into(); + assert_matches!(res, Err(_)); +} + #[test] fn test_u16_index() { const N: usize = 4096;