FEAT: Refactor errors. Insert is either out of bounds or capacity error

This commit is contained in:
bluss
2017-07-30 15:09:02 +02:00
parent 4d7887010e
commit 345dd33942
3 changed files with 31 additions and 23 deletions
+19 -13
View File
@@ -51,15 +51,15 @@ impl<T> fmt::Debug for CapacityError<T> {
} }
pub enum InsertError<T> { pub enum InsertError<T> {
Full(T), Capacity(CapacityError<T>),
OutOfBounds, OutOfBounds(OutOfBoundsError),
} }
impl<T> InsertError<T> { impl<T> InsertError<T> {
fn description(&self) -> &'static str { fn description(&self) -> &'static str {
match *self { match *self {
InsertError::Full(_) => "ArrayVec is already at full capacity", InsertError::Capacity(_) => "ArrayVec is already at full capacity",
InsertError::OutOfBounds => "index is out of bounds", InsertError::OutOfBounds(_) => "index is out of bounds",
} }
} }
} }
@@ -70,6 +70,12 @@ impl<T: Any> Error for InsertError<T> {
fn description(&self) -> &str { fn description(&self) -> &str {
self.description() 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> { impl<T> fmt::Display for InsertError<T> {
@@ -81,20 +87,20 @@ impl<T> fmt::Display for InsertError<T> {
impl<T> fmt::Debug for InsertError<T> { impl<T> fmt::Debug for InsertError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
InsertError::Full(_) => write!(f, "InsertError::Full: ")?, InsertError::Capacity(_) => write!(f, "InsertError::Capacity: ")?,
InsertError::OutOfBounds => write!(f, "InsertError::OutOfBounds: ")?, InsertError::OutOfBounds(_) => write!(f, "InsertError::OutOfBounds: ")?,
} }
write!(f, "{}", self.description()) write!(f, "{}", self.description())
} }
} }
pub struct RemoveError { pub struct OutOfBoundsError {
_priv: () _priv: ()
} }
impl RemoveError { impl OutOfBoundsError {
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
RemoveError { _priv: () } OutOfBoundsError { _priv: () }
} }
fn description(&self) -> &'static str { fn description(&self) -> &'static str {
@@ -104,20 +110,20 @@ impl RemoveError {
#[cfg(feature="std")] #[cfg(feature="std")]
/// Requires `features="std"`. /// Requires `features="std"`.
impl Error for RemoveError { impl Error for OutOfBoundsError {
fn description(&self) -> &str { fn description(&self) -> &str {
self.description() self.description()
} }
} }
impl fmt::Display for RemoveError { impl fmt::Display for OutOfBoundsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description()) write!(f, "{}", self.description())
} }
} }
impl fmt::Debug for RemoveError { impl fmt::Debug for OutOfBoundsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "RemoveError: {}", self.description()) write!(f, "OutOfBoundsError: {}", self.description())
} }
} }
+6 -6
View File
@@ -277,10 +277,10 @@ impl<A: Array> ArrayVec<A> {
/// ``` /// ```
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<(), InsertError<A::Item>> {
if self.len() == self.capacity() { if self.len() == self.capacity() {
return Err(InsertError::Full(element)); return Err(InsertError::Capacity(CapacityError::new(element)));
} }
if index > self.len() { if index > self.len() {
return Err(InsertError::OutOfBounds); return Err(InsertError::OutOfBounds(OutOfBoundsError::new()));
} }
let len = self.len(); let len = self.len();
@@ -365,10 +365,10 @@ impl<A: Array> ArrayVec<A> {
/// ///
/// assert!(array.try_swap_remove(10).is_err()); /// assert!(array.try_swap_remove(10).is_err());
/// ``` /// ```
pub fn try_swap_remove(&mut self, index: usize) -> Result<A::Item, RemoveError> { 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(RemoveError::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(|| panic!())
@@ -411,9 +411,9 @@ impl<A: Array> ArrayVec<A> {
/// assert!(array.try_remove(2).is_err()); /// assert!(array.try_remove(2).is_err());
/// assert!(array.try_remove(10).is_err()); /// assert!(array.try_remove(10).is_err());
/// ``` /// ```
pub fn try_remove(&mut self, index: usize) -> Result<A::Item, RemoveError> { pub fn try_remove(&mut self, index: usize) -> Result<A::Item, OutOfBoundsError> {
if index >= self.len() { if index >= self.len() {
Err(RemoveError::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(|| panic!())
} }
+6 -4
View File
@@ -4,6 +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 std::collections::HashMap; use std::collections::HashMap;
@@ -226,18 +227,19 @@ fn test_insert() {
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);
v.insert(2, 2);
let ret1 = v.try_insert(3, 3); let ret1 = v.try_insert(3, 3);
assert_matches!(ret1, Err(InsertError::OutOfBounds(_)));
assert_eq!(&v[..], &[0, 1]);
v.insert(2, 2);
assert_eq!(&v[..], &[0, 1, 2]); assert_eq!(&v[..], &[0, 1, 2]);
assert_matches!(ret1, Err(_));
let ret2 = v.try_insert(1, 9); let ret2 = v.try_insert(1, 9);
assert_eq!(&v[..], &[0, 1, 2]); assert_eq!(&v[..], &[0, 1, 2]);
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(_)); assert_matches!(v.try_insert(1, 1), Err(InsertError::Capacity(_)));
assert_matches!(v.try_insert(2, 1), Err(_)); assert_matches!(v.try_insert(2, 1), Err(InsertError::Capacity(_)));
} }
#[test] #[test]