From 97f8662ae5d4fa7581e7ff3c213c0994c39b5f3e Mon Sep 17 00:00:00 2001 From: Caio Date: Wed, 27 Oct 2021 18:27:21 -0300 Subject: [PATCH] Implement TryFrom> for ArrayVec --- src/arrayvec.rs | 26 ++++++++++++++++++++++++++ src/lib.rs | 8 ++++++++ tests/tests.rs | 11 ++++++++--- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/arrayvec.rs b/src/arrayvec.rs index 6b4faf8..8dd5991 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -772,6 +772,32 @@ impl std::convert::TryFrom<&[T]> for ArrayVec } +/// Try to create an `ArrayVec` from a vector. 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> = vec![1, 2, 3].try_into().unwrap(); +/// assert_eq!(array.len(), 3); +/// assert_eq!(array.capacity(), 4); +/// ``` +impl std::convert::TryFrom> for ArrayVec { + type Error = CapacityError; + + fn try_from(vec: crate::Vec) -> Result { + if Self::CAPACITY < vec.len() { + Err(CapacityError::new(())) + } else { + let mut array = Self::new(); + // SAFETY: Vector length has already been checked + unsafe { array.extend_from_iter::<_, false>(vec); } + Ok(array) + } + } +} + /// Iterate the `ArrayVec` with references to each element. /// /// ``` diff --git a/src/lib.rs b/src/lib.rs index 5dc0273..257b9c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,12 +18,20 @@ #![doc(html_root_url="https://docs.rs/arrayvec/0.7/")] #![cfg_attr(not(feature="std"), no_std)] +#[cfg(not(feature="std"))] +extern crate alloc; + #[cfg(feature="serde")] extern crate serde; #[cfg(not(feature="std"))] extern crate core as std; +#[cfg(feature="std")] +pub use std::vec::Vec as Vec; +#[cfg(not(feature="std"))] +pub use alloc::vec::Vec as Vec; + pub(crate) type LenUint = u32; macro_rules! assert_capacity_limit { diff --git a/tests/tests.rs b/tests/tests.rs index 2f8a5ef..b1893f1 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -6,9 +6,6 @@ use arrayvec::ArrayString; use std::mem; use arrayvec::CapacityError; -use std::collections::HashMap; - - #[test] fn test_simple() { use std::ops::Add; @@ -523,6 +520,7 @@ fn array_clone_from() { #[cfg(feature="std")] #[test] fn test_string() { + use std::collections::HashMap; use std::error::Error; let text = "hello world"; @@ -790,4 +788,11 @@ fn test_arraystring_zero_filled_has_some_sanity_checks() { let string = ArrayString::<4>::zero_filled(); assert_eq!(string.as_str(), "\0\0\0\0"); assert_eq!(string.len(), 4); +} + +#[test] +fn try_from_vec_returns_correct_values() { + use core::convert::TryFrom; + assert!(ArrayVec::<_, 1>::try_from(vec![1]).is_ok()); + assert!(ArrayVec::<_, 1>::try_from(vec![1, 2]).is_err()); } \ No newline at end of file