From 47827e4843ed86682ca8e1a025e44f0152ebf67a Mon Sep 17 00:00:00 2001 From: bluss Date: Wed, 28 Nov 2018 15:59:11 +0100 Subject: [PATCH] FIX: Remake extend_from_slice to try_extend_from_slice Do nothing and return an error, if the slice doesn't fit in the remaining capacity. --- benches/extend.rs | 2 +- src/lib.rs | 17 ++++++++++------- tests/tests.rs | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/benches/extend.rs b/benches/extend.rs index fe9fd96..9edc4fb 100644 --- a/benches/extend.rs +++ b/benches/extend.rs @@ -45,7 +45,7 @@ fn extend_with_slice_fn(b: &mut Bencher) { let data = [1; 512]; b.iter(|| { v.clear(); - black_box(v.extend_from_slice(&data)); + black_box(v.try_extend_from_slice(&data)); v[0] }); b.bytes = v.capacity() as u64; diff --git a/src/lib.rs b/src/lib.rs index 4d83a1f..5dedb9c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -543,21 +543,22 @@ impl ArrayVec { /// /// let mut vec: ArrayVec<[usize; 10]> = ArrayVec::new(); /// vec.push(1); - /// vec.extend_from_slice(&[2, 3]); + /// vec.try_extend_from_slice(&[2, 3]).unwrap(); /// assert_eq!(&vec[..], &[1, 2, 3]); /// ``` /// - /// # Panics + /// # Errors /// - /// This method will panic if the capacity left (see [`remaining_capacity`]) is - /// smaller then the length of the provided slice. + /// This method will return an error if the capacity left (see + /// [`remaining_capacity`]) is smaller then the length of the provided + /// slice. /// /// [`remaining_capacity`]: #method.remaining_capacity - pub fn extend_from_slice(&mut self, other: &[A::Item]) + pub fn try_extend_from_slice(&mut self, other: &[A::Item]) -> Result<(), CapacityError> where A::Item: Copy, { if self.remaining_capacity() < other.len() { - panic!("ArrayVec::extend_from_slice: slice is larger then capacity left"); + return Err(CapacityError::new(())); } let self_len = self.len(); @@ -568,6 +569,7 @@ impl ArrayVec { ptr::copy_nonoverlapping(other.as_ptr(), dst, other_len); self.set_len(self_len + other_len); } + Ok(()) } /// Create a draining iterator that removes the specified range in the vector @@ -1080,7 +1082,8 @@ impl Ord for ArrayVec where A::Item: Ord { impl> io::Write for ArrayVec { fn write(&mut self, data: &[u8]) -> io::Result { let len = cmp::min(self.remaining_capacity(), data.len()); - self.extend_from_slice(&data[..len]); + let _result = self.try_extend_from_slice(&data[..len]); + debug_assert!(_result.is_ok()); Ok(len) } fn flush(&mut self) -> io::Result<()> { Ok(()) } diff --git a/tests/tests.rs b/tests/tests.rs index 5b8b5e4..e35d97a 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -45,7 +45,7 @@ fn test_capacity_left() { fn test_extend_from_slice() { let mut vec: ArrayVec<[usize; 10]> = ArrayVec::new(); - vec.extend_from_slice(&[1, 2, 3]); + vec.try_extend_from_slice(&[1, 2, 3]); assert_eq!(vec.len(), 3); assert_eq!(&vec[..], &[1, 2, 3]); assert_eq!(vec.pop(), Some(3));