FEAT: Remove InsertError again

try_insert has a capacity error, but panics if the index is out of
bounds.
This commit is contained in:
bluss
2017-08-05 17:40:12 +02:00
parent 1e83039426
commit bc9e0362bd
4 changed files with 36 additions and 71 deletions
+1
View File
@@ -12,6 +12,7 @@ use std::slice;
use array::{Array, ArrayExt}; use array::{Array, ArrayExt};
use array::Index; use array::Index;
use CapacityError; use CapacityError;
use errors::PubCrateNew;
use odds::char::encode_utf8; use odds::char::encode_utf8;
#[cfg(feature="serde-1")] #[cfg(feature="serde-1")]
+13 -48
View File
@@ -10,13 +10,19 @@ pub struct CapacityError<T = ()> {
element: T, element: T,
} }
impl<T> CapacityError<T> { pub trait PubCrateNew<T> {
pub(crate) fn new(element: T) -> CapacityError<T> { fn new(elt: T) -> Self;
}
impl<T> PubCrateNew<T> for CapacityError<T> {
fn new(element: T) -> CapacityError<T> {
CapacityError { CapacityError {
element: element, element: element,
} }
} }
}
impl<T> CapacityError<T> {
/// Extract the overflowing element /// Extract the overflowing element
pub fn element(self) -> T { pub fn element(self) -> T {
self.element self.element
@@ -50,59 +56,18 @@ impl<T> fmt::Debug for CapacityError<T> {
} }
} }
pub enum InsertError<T> {
Capacity(CapacityError<T>),
OutOfBounds(OutOfBoundsError),
}
impl<T> InsertError<T> {
fn description(&self) -> &'static str {
match *self {
InsertError::Capacity(_) => "ArrayVec is already at full capacity",
InsertError::OutOfBounds(_) => "index is out of bounds",
}
}
}
#[cfg(feature="std")]
/// Requires `features="std"`.
impl<T: Any> Error for InsertError<T> {
fn description(&self) -> &str {
self.description()
}
fn cause(&self) -> Option<&Error> {
match *self {
InsertError::Capacity(ref e) => Some(e as &Error),
InsertError::OutOfBounds(ref e) => Some(e as &Error),
}
}
}
impl<T> fmt::Display for InsertError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl<T> fmt::Debug for InsertError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
InsertError::Capacity(_) => write!(f, "InsertError::Capacity: ")?,
InsertError::OutOfBounds(_) => write!(f, "InsertError::OutOfBounds: ")?,
}
write!(f, "{}", self.description())
}
}
pub struct OutOfBoundsError { pub struct OutOfBoundsError {
_priv: () _priv: ()
} }
impl OutOfBoundsError { impl PubCrateNew<()> for OutOfBoundsError {
pub(crate) fn new() -> Self { fn new(_: ()) -> Self {
OutOfBoundsError { _priv: () } OutOfBoundsError { _priv: () }
} }
}
impl OutOfBoundsError {
fn description(&self) -> &'static str { fn description(&self) -> &'static str {
"remove index is out of bounds" "remove index is out of bounds"
} }
+14 -13
View File
@@ -256,12 +256,14 @@ impl<A: Array> ArrayVec<A> {
/// Insert `element` in position `index`. /// Insert `element` in position `index`.
/// ///
/// Shift up all elements after `index`. /// Shift up all elements after `index`; the `index` must be less than
/// or equal to the length.
/// ///
/// Returns an error if /// Returns an error if:
/// ///
/// - The vector is at full capacity /// - The vector is at full capacity
/// - The index is out of bounds ///
/// ***Panics*** `index` is out of bounds.
/// ///
/// ``` /// ```
/// use arrayvec::ArrayVec; /// use arrayvec::ArrayVec;
@@ -269,18 +271,17 @@ impl<A: Array> ArrayVec<A> {
/// let mut array = ArrayVec::<[_; 2]>::new(); /// let mut array = ArrayVec::<[_; 2]>::new();
/// ///
/// assert!(array.try_insert(0, "x").is_ok()); /// assert!(array.try_insert(0, "x").is_ok());
/// assert!(array.try_insert(3, "w").is_err());
/// assert!(array.try_insert(0, "y").is_ok()); /// assert!(array.try_insert(0, "y").is_ok());
/// assert!(array.try_insert(0, "z").is_err()); /// assert!(array.try_insert(0, "z").is_err());
/// assert_eq!(&array[..], &["y", "x"]); /// assert_eq!(&array[..], &["y", "x"]);
/// ///
/// ``` /// ```
pub fn try_insert(&mut self, index: usize, element: A::Item) -> Result<(), InsertError<A::Item>> { pub fn try_insert(&mut self, index: usize, element: A::Item) -> Result<(), CapacityError<A::Item>> {
if self.len() == self.capacity() {
return Err(InsertError::Capacity(CapacityError::new(element)));
}
if index > self.len() { if index > self.len() {
return Err(InsertError::OutOfBounds(OutOfBoundsError::new())); panic!("ArrayVec::try_insert: {} is out of bounds (length is {})", index, self.len());
}
if self.len() == self.capacity() {
return Err(CapacityError::new(element));
} }
let len = self.len(); let len = self.len();
@@ -368,10 +369,10 @@ impl<A: Array> ArrayVec<A> {
pub fn try_swap_remove(&mut self, index: usize) -> Result<A::Item, OutOfBoundsError> { pub fn try_swap_remove(&mut self, index: usize) -> Result<A::Item, OutOfBoundsError> {
let len = self.len(); let len = self.len();
if index >= len { if index >= len {
return Err(OutOfBoundsError::new()) return Err(OutOfBoundsError::new(()))
} }
self.swap(index, len - 1); self.swap(index, len - 1);
self.pop().ok_or_else(|| panic!()) self.pop().ok_or_else(|| unreachable!())
} }
/// Remove the element at `index` and shift down the following elements. /// Remove the element at `index` and shift down the following elements.
@@ -413,9 +414,9 @@ impl<A: Array> ArrayVec<A> {
/// ``` /// ```
pub fn try_remove(&mut self, index: usize) -> Result<A::Item, OutOfBoundsError> { pub fn try_remove(&mut self, index: usize) -> Result<A::Item, OutOfBoundsError> {
if index >= self.len() { if index >= self.len() {
Err(OutOfBoundsError::new()) Err(OutOfBoundsError::new(()))
} else { } else {
self.drain(index..index + 1).next().ok_or_else(|| panic!()) self.drain(index..index + 1).next().ok_or_else(|| unreachable!())
} }
} }
+8 -10
View File
@@ -4,7 +4,7 @@ extern crate arrayvec;
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use arrayvec::ArrayString; use arrayvec::ArrayString;
use std::mem; use std::mem;
use arrayvec::errors::InsertError; use arrayvec::errors::CapacityError;
use std::collections::HashMap; use std::collections::HashMap;
@@ -222,13 +222,12 @@ fn test_drop_panic_into_iter() {
fn test_insert() { fn test_insert() {
let mut v = ArrayVec::from([]); let mut v = ArrayVec::from([]);
assert_matches!(v.try_push(1), Err(_)); assert_matches!(v.try_push(1), Err(_));
assert_matches!(v.try_insert(0, 1), Err(_));
let mut v = ArrayVec::<[_; 3]>::new(); let mut v = ArrayVec::<[_; 3]>::new();
v.insert(0, 0); v.insert(0, 0);
v.insert(1, 1); v.insert(1, 1);
let ret1 = v.try_insert(3, 3); //let ret1 = v.try_insert(3, 3);
assert_matches!(ret1, Err(InsertError::OutOfBounds(_))); //assert_matches!(ret1, Err(InsertError::OutOfBounds(_)));
assert_eq!(&v[..], &[0, 1]); assert_eq!(&v[..], &[0, 1]);
v.insert(2, 2); v.insert(2, 2);
assert_eq!(&v[..], &[0, 1, 2]); assert_eq!(&v[..], &[0, 1, 2]);
@@ -238,8 +237,9 @@ fn test_insert() {
assert_matches!(ret2, Err(_)); assert_matches!(ret2, Err(_));
let mut v = ArrayVec::from([2]); let mut v = ArrayVec::from([2]);
assert_matches!(v.try_insert(1, 1), Err(InsertError::Capacity(_))); assert_matches!(v.try_insert(0, 1), Err(CapacityError { .. }));
assert_matches!(v.try_insert(2, 1), Err(InsertError::Capacity(_))); assert_matches!(v.try_insert(1, 1), Err(CapacityError { .. }));
//assert_matches!(v.try_insert(2, 1), Err(CapacityError { .. }));
} }
#[test] #[test]
@@ -386,13 +386,11 @@ fn test_insert_at_length() {
assert_eq!(&v[..], &["a", "b"]); assert_eq!(&v[..], &["a", "b"]);
} }
#[should_panic]
#[test] #[test]
fn test_insert_out_of_bounds() { fn test_insert_out_of_bounds() {
let mut v = ArrayVec::<[_; 8]>::new(); let mut v = ArrayVec::<[_; 8]>::new();
let result = v.try_insert(1, "test"); let _ = v.try_insert(1, "test");
assert_matches!(result, Err(_));
assert_eq!(v.len(), 0);
} }
/* /*