diff --git a/src/lib.rs b/src/lib.rs index 848c5a5..0268334 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -708,6 +708,35 @@ 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 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: Clone, +{ + type Error = CapacityError; + + fn try_from(slice: &[A::Item]) -> Result { + if A::CAPACITY < slice.len() { + Err(CapacityError::new(())) + } else { + let mut array = Self::new(); + array.extend(slice.iter().cloned()); + Ok(array) + } + } +} + + /// Iterate the `ArrayVec` with references to each element. /// /// ``` 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;