Merge pull request #61 from bluss/vec-like-api

Prepare 0.4, more vec-like api and error reform
This commit is contained in:
bluss
2017-08-06 00:48:10 +02:00
committed by GitHub
8 changed files with 373 additions and 139 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ env:
- FEATURES='serde-1'
matrix:
include:
- rust: 1.12.0
- rust: 1.15.0
- rust: stable
env:
- NODEFAULT=1
+6
View File
@@ -27,8 +27,14 @@ default-features = false
[dev-dependencies.serde_test]
version = "1.0"
[dev-dependencies]
matches = { version = "0.1" }
[features]
default = ["std"]
std = ["odds/std", "nodrop/std"]
use_union = ["nodrop/use_union"]
serde-1 = ["serde"]
[package.metadata.docs.rs]
features = ["serde-1"]
+1 -1
View File
@@ -2,7 +2,7 @@
arrayvec
========
A vector with fixed capacity. Requires Rust 1.12.0 or later.
A vector with fixed capacity.
Please read the `API documentation here`__
+56 -14
View File
@@ -12,6 +12,7 @@ use std::slice;
use array::{Array, ArrayExt};
use array::Index;
use CapacityError;
use errors::PubCrateNew;
use odds::char::encode_utf8;
#[cfg(feature="serde-1")]
@@ -68,7 +69,7 @@ impl<A: Array<Item=u8>> ArrayString<A> {
/// ```
pub fn from(s: &str) -> Result<Self, CapacityError<&str>> {
let mut arraystr = Self::new();
try!(arraystr.push_str(s));
arraystr.try_push_str(s)?;
Ok(arraystr)
}
@@ -84,7 +85,7 @@ impl<A: Array<Item=u8>> ArrayString<A> {
pub fn from_byte_string(b: &A) -> Result<Self, Utf8Error> {
let mut arraystr = Self::new();
let s = try!(str::from_utf8(b.as_slice()));
let _result = arraystr.push_str(s);
let _result = arraystr.try_push_str(s);
debug_assert!(_result.is_ok());
Ok(arraystr)
}
@@ -123,14 +124,34 @@ impl<A: Array<Item=u8>> ArrayString<A> {
///
/// let mut string = ArrayString::<[_; 2]>::new();
///
/// string.push('a').unwrap();
/// string.push('b').unwrap();
/// let overflow = string.push('c');
/// string.push('a');
/// string.push('b');
///
/// assert_eq!(&string[..], "ab");
/// ```
pub fn push(&mut self, c: char) {
self.try_push(c).unwrap();
}
/// Adds the given char to the end of the string.
///
/// Returns `Ok` if the push succeeds.
///
/// **Errors** if the backing array is not large enough to fit the additional char.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<[_; 2]>::new();
///
/// string.try_push('a').unwrap();
/// string.try_push('b').unwrap();
/// let overflow = string.try_push('c');
///
/// assert_eq!(&string[..], "ab");
/// assert_eq!(overflow.unwrap_err().element(), 'c');
/// ```
pub fn push(&mut self, c: char) -> Result<(), CapacityError<char>> {
pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> {
let len = self.len();
unsafe {
match encode_utf8(c, &mut self.raw_mut_bytes()[len..]) {
@@ -154,16 +175,36 @@ impl<A: Array<Item=u8>> ArrayString<A> {
///
/// let mut string = ArrayString::<[_; 2]>::new();
///
/// string.push_str("a").unwrap();
/// let overflow1 = string.push_str("bc");
/// string.push_str("d").unwrap();
/// let overflow2 = string.push_str("ef");
/// string.push_str("a");
/// string.push_str("d");
///
/// assert_eq!(&string[..], "ad");
/// ```
pub fn push_str(&mut self, s: &str) {
self.try_push_str(s).unwrap()
}
/// Adds the given string slice to the end of the string.
///
/// Returns `Ok` if the push succeeds.
///
/// **Errors** if the backing array is not large enough to fit the string.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<[_; 2]>::new();
///
/// string.try_push_str("a").unwrap();
/// let overflow1 = string.try_push_str("bc");
/// string.try_push_str("d").unwrap();
/// let overflow2 = string.try_push_str("ef");
///
/// assert_eq!(&string[..], "ad");
/// assert_eq!(overflow1.unwrap_err().element(), "bc");
/// assert_eq!(overflow2.unwrap_err().element(), "ef");
/// ```
pub fn push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
if s.len() > self.capacity() - self.len() {
return Err(CapacityError::new(s));
}
@@ -274,10 +315,11 @@ impl<A: Array<Item=u8>> fmt::Display for ArrayString<A> {
/// `Write` appends written data to the end of the string.
impl<A: Array<Item=u8>> fmt::Write for ArrayString<A> {
fn write_char(&mut self, c: char) -> fmt::Result {
self.push(c).map_err(|_| fmt::Error)
self.try_push(c).map_err(|_| fmt::Error)
}
fn write_str(&mut self, s: &str) -> fmt::Result {
self.push_str(s).map_err(|_| fmt::Error)
self.try_push_str(s).map_err(|_| fmt::Error)
}
}
@@ -288,7 +330,7 @@ impl<A: Array<Item=u8> + Copy> Clone for ArrayString<A> {
fn clone_from(&mut self, rhs: &Self) {
// guaranteed to fit due to types matching.
self.clear();
self.push_str(rhs).ok();
self.try_push_str(rhs).ok();
}
}
+58
View File
@@ -0,0 +1,58 @@
use std::fmt;
#[cfg(feature="std")]
use std::any::Any;
#[cfg(feature="std")]
use std::error::Error;
/// Error value indicating insufficient capacity
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
pub struct CapacityError<T = ()> {
element: T,
}
pub trait PubCrateNew<T> {
fn new(elt: T) -> Self;
}
impl<T> PubCrateNew<T> for CapacityError<T> {
fn new(element: T) -> CapacityError<T> {
CapacityError {
element: element,
}
}
}
impl<T> CapacityError<T> {
/// Extract the overflowing element
pub fn element(self) -> T {
self.element
}
/// Convert into a `CapacityError` that does not carry an element.
pub fn simplify(self) -> CapacityError {
CapacityError { element: () }
}
}
const CAPERROR: &'static str = "insufficient capacity";
#[cfg(feature="std")]
/// Requires `features="std"`.
impl<T: Any> Error for CapacityError<T> {
fn description(&self) -> &str {
CAPERROR
}
}
impl<T> fmt::Display for CapacityError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", CAPERROR)
}
}
impl<T> fmt::Debug for CapacityError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: {}", "CapacityError", CAPERROR)
}
}
+149 -89
View File
@@ -5,7 +5,6 @@
//!
//! - `std`
//! - Optional, enabled by default
//! - Requires Rust 1.6 *to disable*
//! - Use libstd
//!
//! - `use_union`
@@ -14,6 +13,10 @@
//! - Use the unstable feature untagged unions for the internal implementation,
//! which has reduced space overhead
//!
//! ## Rust Version
//!
//! This version of arrayvec requires Rust 1.15 or later.
//!
#![doc(html_root_url="https://docs.rs/arrayvec/0.3/")]
#![cfg_attr(not(feature="std"), no_std)]
extern crate odds;
@@ -41,10 +44,6 @@ use std::fmt;
#[cfg(feature="std")]
use std::io;
#[cfg(feature="std")]
use std::error::Error;
#[cfg(feature="std")]
use std::any::Any; // core but unused
use nodrop::NoDrop;
@@ -53,11 +52,15 @@ use serde::{Serialize, Deserialize, Serializer, Deserializer};
mod array;
mod array_string;
mod range;
mod errors;
pub use array::Array;
pub use odds::IndexRange as RangeArgument;
pub use range::RangeArgument;
use array::Index;
pub use array_string::ArrayString;
use errors::PubCrateNew;
pub use errors::CapacityError;
unsafe fn new_array<A: Array>() -> A {
@@ -95,6 +98,13 @@ impl<A: Array> Drop for ArrayVec<A> {
}
}
macro_rules! panic_oob {
($method_name:expr, $index:expr, $len:expr) => {
panic!(concat!("ArrayVec::", $method_name, ": index {} is out of bounds in vector of length {}"),
$index, $len)
}
}
impl<A: Array> ArrayVec<A> {
/// Create a new empty `ArrayVec`.
///
@@ -152,8 +162,7 @@ impl<A: Array> ArrayVec<A> {
/// Push `element` to the end of the vector.
///
/// Return `None` if the push succeeds, or and return `Some(` *element* `)`
/// if the vector is full.
/// ***Panics*** if the vector is already full.
///
/// ```
/// use arrayvec::ArrayVec;
@@ -162,28 +171,53 @@ impl<A: Array> ArrayVec<A> {
///
/// array.push(1);
/// array.push(2);
/// let overflow = array.push(3);
///
/// assert_eq!(&array[..], &[1, 2]);
/// assert_eq!(overflow, Some(3));
/// ```
pub fn push(&mut self, element: A::Item) -> Option<A::Item> {
pub fn push(&mut self, element: A::Item) {
self.try_push(element).unwrap()
}
/// Push `element` to the end of the vector.
///
/// Return `Ok` if the push succeeds, or return an error if the vector
/// is already full.
///
/// ```
/// use arrayvec::ArrayVec;
///
/// let mut array = ArrayVec::<[_; 2]>::new();
///
/// let push1 = array.try_push(1);
/// let push2 = array.try_push(2);
///
/// assert!(push1.is_ok());
/// assert!(push2.is_ok());
///
/// assert_eq!(&array[..], &[1, 2]);
///
/// let overflow = array.try_push(3);
///
/// assert!(overflow.is_err());
/// ```
pub fn try_push(&mut self, element: A::Item) -> Result<(), CapacityError<A::Item>> {
if self.len() < A::capacity() {
unsafe {
self.push_unchecked(element);
}
None
Ok(())
} else {
Some(element)
Err(CapacityError::new(element))
}
}
/// Push `element` to the end of the vector without checking the capacity.
///
/// It is up to the caller to ensure the capacity of the vector is
/// sufficiently large.
///
/// # Examples
/// This method *may* use debug assertions to check that the arrayvec is not full.
///
/// ```
/// use arrayvec::ArrayVec;
@@ -207,35 +241,55 @@ impl<A: Array> ArrayVec<A> {
self.set_len(len + 1);
}
/// Insert `element` in position `index`.
/// Insert `element` at position `index`.
///
/// Shift up all elements after `index`. If any is pushed out, it is returned.
/// Shift up all elements after `index`.
///
/// Return `None` if no element is shifted out.
/// It is an error if the index is greater than the length or if the
/// arrayvec is full.
///
/// `index` must be <= `self.len()` and < `self.capacity()`. Note that any
/// out of bounds index insert results in the element being "shifted out"
/// and returned directly.
/// ***Panics*** on errors. See `try_result` for fallible version.
///
/// ```
/// use arrayvec::ArrayVec;
///
/// let mut array = ArrayVec::<[_; 2]>::new();
///
/// assert_eq!(array.insert(0, "x"), None);
/// assert_eq!(array.insert(0, "y"), None);
/// assert_eq!(array.insert(0, "z"), Some("x"));
/// assert_eq!(array.insert(1, "w"), Some("y"));
/// assert_eq!(&array[..], &["z", "w"]);
/// array.insert(0, "x");
/// array.insert(0, "y");
/// assert_eq!(&array[..], &["y", "x"]);
///
/// ```
pub fn insert(&mut self, index: usize, element: A::Item) -> Option<A::Item> {
if index > self.len() || index == self.capacity() {
return Some(element);
pub fn insert(&mut self, index: usize, element: A::Item) {
self.try_insert(index, element).unwrap()
}
/// Insert `element` at position `index`.
///
/// Shift up all elements after `index`; the `index` must be less than
/// or equal to the length.
///
/// Returns an error if vector is already at full capacity.
///
/// ***Panics*** `index` is out of bounds.
///
/// ```
/// use arrayvec::ArrayVec;
///
/// let mut array = ArrayVec::<[_; 2]>::new();
///
/// assert!(array.try_insert(0, "x").is_ok());
/// assert!(array.try_insert(0, "y").is_ok());
/// assert!(array.try_insert(0, "z").is_err());
/// assert_eq!(&array[..], &["y", "x"]);
///
/// ```
pub fn try_insert(&mut self, index: usize, element: A::Item) -> Result<(), CapacityError<A::Item>> {
if index > self.len() {
panic_oob!("try_insert", index, self.len())
}
let mut ret = None;
if self.len() == self.capacity() {
ret = self.pop();
return Err(CapacityError::new(element));
}
let len = self.len();
@@ -253,10 +307,10 @@ impl<A: Array> ArrayVec<A> {
}
self.set_len(len + 1);
}
ret
Ok(())
}
/// Remove the last element in the vector.
/// Remove the last element in the vector and return it.
///
/// Return `Some(` *element* `)` if the vector is non-empty, else `None`.
///
@@ -285,6 +339,33 @@ impl<A: Array> ArrayVec<A> {
///
/// This operation is O(1).
///
/// Return the *element* if the index is in bounds, else panic.
///
/// ***Panics*** if the `index` is out of bounds.
///
/// ```
/// use arrayvec::ArrayVec;
///
/// let mut array = ArrayVec::from([1, 2, 3]);
///
/// assert_eq!(array.swap_remove(0), 1);
/// assert_eq!(&array[..], &[3, 2]);
///
/// assert_eq!(array.swap_remove(1), 2);
/// assert_eq!(&array[..], &[3]);
/// ```
pub fn swap_remove(&mut self, index: usize) -> A::Item {
self.swap_pop(index)
.unwrap_or_else(|| {
panic_oob!("swap_remove", index, self.len())
})
}
/// Remove the element at `index` and swap the last element into its place.
///
/// This is a checked version of `.swap_remove`.
/// This operation is O(1).
///
/// Return `Some(` *element* `)` if the index is in bounds, else `None`.
///
/// ```
@@ -292,15 +373,15 @@ impl<A: Array> ArrayVec<A> {
///
/// let mut array = ArrayVec::from([1, 2, 3]);
///
/// assert_eq!(array.swap_remove(0), Some(1));
/// assert_eq!(array.swap_pop(0), Some(1));
/// assert_eq!(&array[..], &[3, 2]);
///
/// assert_eq!(array.swap_remove(10), None);
/// assert_eq!(array.swap_pop(10), None);
/// ```
pub fn swap_remove(&mut self, index: usize) -> Option<A::Item> {
pub fn swap_pop(&mut self, index: usize) -> Option<A::Item> {
let len = self.len();
if index >= len {
return None
return None;
}
self.swap(index, len - 1);
self.pop()
@@ -308,19 +389,43 @@ impl<A: Array> ArrayVec<A> {
/// Remove the element at `index` and shift down the following elements.
///
/// Return `Some(` *element* `)` if the index is in bounds, else `None`.
/// The `index` must be strictly less than the length of the vector.
///
/// ***Panics*** if the `index` is out of bounds.
///
/// ```
/// use arrayvec::ArrayVec;
///
/// let mut array = ArrayVec::from([1, 2, 3]);
///
/// assert_eq!(array.remove(0), Some(1));
/// let removed_elt = array.remove(0);
/// assert_eq!(removed_elt, 1);
/// assert_eq!(&array[..], &[2, 3]);
/// ```
pub fn remove(&mut self, index: usize) -> A::Item {
self.pop_at(index)
.unwrap_or_else(|| {
panic_oob!("remove", index, self.len())
})
}
/// Remove the element at `index` and shift down the following elements.
///
/// This is a checked version of `.remove(index)`. Returns `None` if there
/// is no element at `index`. Otherwise, return the element inside `Some`.
///
/// ```
/// use arrayvec::ArrayVec;
///
/// let mut array = ArrayVec::from([1, 2, 3]);
///
/// assert!(array.pop_at(0).is_some());
/// assert_eq!(&array[..], &[2, 3]);
///
/// assert_eq!(array.remove(10), None);
/// assert!(array.pop_at(2).is_none());
/// assert!(array.pop_at(10).is_none());
/// ```
pub fn remove(&mut self, index: usize) -> Option<A::Item> {
pub fn pop_at(&mut self, index: usize) -> Option<A::Item> {
if index >= self.len() {
None
} else {
@@ -369,7 +474,8 @@ impl<A: Array> ArrayVec<A> {
/// Set the vector's length without dropping or moving out elements
///
/// May panic if `length` is greater than the capacity.
/// May use debug assertions to check that `length` is not greater than the
/// capacity.
///
/// This function is `unsafe` because it changes the notion of the
/// number of “valid” elements in the vector. Use with care.
@@ -394,7 +500,7 @@ impl<A: Array> ArrayVec<A> {
/// use arrayvec::ArrayVec;
///
/// let mut v = ArrayVec::from([1, 2, 3]);
/// let u: Vec<_> = v.drain(0..2).collect();
/// let u: ArrayVec<[_; 3]> = v.drain(0..2).collect();
/// assert_eq!(&v[..], &[3]);
/// assert_eq!(&u[..], &[1, 2]);
/// ```
@@ -887,7 +993,7 @@ impl<'de, T: Deserialize<'de>, A: Array<Item=T>> Deserialize<'de> for ArrayVec<A
let mut values = ArrayVec::<A>::new();
while let Some(value) = try!(seq.next_element()) {
if let Some(_) = values.push(value) {
if let Err(_) = values.try_push(value) {
return Err(SA::Error::invalid_length(A::capacity() + 1, &self));
}
}
@@ -899,49 +1005,3 @@ impl<'de, T: Deserialize<'de>, A: Array<Item=T>> Deserialize<'de> for ArrayVec<A
deserializer.deserialize_seq(ArrayVecVisitor::<T, A>(PhantomData))
}
}
/// Error value indicating insufficient capacity
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
pub struct CapacityError<T = ()> {
element: T,
}
impl<T> CapacityError<T> {
fn new(element: T) -> CapacityError<T> {
CapacityError {
element: element,
}
}
/// Extract the overflowing element
pub fn element(self) -> T {
self.element
}
/// Convert into a `CapacityError` that does not carry an element.
pub fn simplify(self) -> CapacityError {
CapacityError { element: () }
}
}
const CAPERROR: &'static str = "insufficient capacity";
#[cfg(feature="std")]
/// Requires `features="std"`.
impl<T: Any> Error for CapacityError<T> {
fn description(&self) -> &str {
CAPERROR
}
}
impl<T> fmt::Display for CapacityError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", CAPERROR)
}
}
impl<T> fmt::Debug for CapacityError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: {}", "CapacityError", CAPERROR)
}
}
+42
View File
@@ -0,0 +1,42 @@
use std::ops::{
RangeFull,
RangeFrom,
RangeTo,
Range,
};
/// `RangeArgument` is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
///
/// Note: This is arrayvec's provisional trait, waiting for stable Rust to
/// provide an equivalent.
pub trait RangeArgument {
#[inline]
/// Start index (inclusive)
fn start(&self) -> Option<usize> { None }
#[inline]
/// End index (exclusive)
fn end(&self) -> Option<usize> { None }
}
impl RangeArgument for RangeFull {}
impl RangeArgument for RangeFrom<usize> {
#[inline]
fn start(&self) -> Option<usize> { Some(self.start) }
}
impl RangeArgument for RangeTo<usize> {
#[inline]
fn end(&self) -> Option<usize> { Some(self.end) }
}
impl RangeArgument for Range<usize> {
#[inline]
fn start(&self) -> Option<usize> { Some(self.start) }
#[inline]
fn end(&self) -> Option<usize> { Some(self.end) }
}
+60 -34
View File
@@ -1,8 +1,10 @@
extern crate arrayvec;
#[macro_use] extern crate matches;
use arrayvec::ArrayVec;
use arrayvec::ArrayString;
use std::mem;
use arrayvec::CapacityError;
use std::collections::HashMap;
@@ -30,9 +32,9 @@ fn test_u16_index() {
const N: usize = 4096;
let mut vec: ArrayVec<[_; N]> = ArrayVec::new();
for _ in 0..N {
assert!(vec.push(1u8).is_none());
assert!(vec.try_push(1u8).is_ok());
}
assert!(vec.push(0).is_some());
assert!(vec.try_push(0).is_err());
assert_eq!(vec.len(), N);
}
@@ -77,7 +79,9 @@ fn test_drop() {
array.push(vec![Bump(flag)]);
array.push(vec![Bump(flag), Bump(flag)]);
array.push(vec![]);
array.push(vec![Bump(flag)]);
let push4 = array.try_push(vec![Bump(flag)]);
assert_eq!(flag.get(), 0);
drop(push4);
assert_eq!(flag.get(), 1);
drop(array.pop());
assert_eq!(flag.get(), 1);
@@ -217,21 +221,25 @@ fn test_drop_panic_into_iter() {
#[test]
fn test_insert() {
let mut v = ArrayVec::from([]);
assert_eq!(v.push(1), Some(1));
assert_eq!(v.insert(0, 1), Some(1));
assert_matches!(v.try_push(1), Err(_));
let mut v = ArrayVec::<[_; 3]>::new();
v.insert(0, 0);
v.insert(1, 1);
//let ret1 = v.try_insert(3, 3);
//assert_matches!(ret1, Err(InsertError::OutOfBounds(_)));
assert_eq!(&v[..], &[0, 1]);
v.insert(2, 2);
v.insert(3, 3);
assert_eq!(&v[..], &[0, 1, 2]);
v.insert(1, 9);
assert_eq!(&v[..], &[0, 9, 1]);
let ret2 = v.try_insert(1, 9);
assert_eq!(&v[..], &[0, 1, 2]);
assert_matches!(ret2, Err(_));
let mut v = ArrayVec::from([2]);
assert_eq!(v.insert(1, 1), Some(1));
assert_eq!(v.insert(2, 1), Some(1));
assert_matches!(v.try_insert(0, 1), Err(CapacityError { .. }));
assert_matches!(v.try_insert(1, 1), Err(CapacityError { .. }));
//assert_matches!(v.try_insert(2, 1), Err(CapacityError { .. }));
}
#[test]
@@ -299,7 +307,7 @@ fn test_string() {
let text = "hello world";
let mut s = ArrayString::<[_; 16]>::new();
s.push_str(text).unwrap();
s.try_push_str(text).unwrap();
assert_eq!(&s, text);
assert_eq!(text, &s);
@@ -309,10 +317,10 @@ fn test_string() {
assert_eq!(map[text], 1);
let mut t = ArrayString::<[_; 2]>::new();
assert!(t.push_str(text).is_err());
assert!(t.try_push_str(text).is_err());
assert_eq!(&t, "");
t.push_str("ab").unwrap();
t.push_str("ab");
// DerefMut
let tmut: &mut str = &mut t;
assert_eq!(tmut, "ab");
@@ -320,7 +328,7 @@ fn test_string() {
// Test Error trait / try
let t = || -> Result<(), Box<Error>> {
let mut t = ArrayString::<[_; 2]>::new();
try!(t.push_str(text));
try!(t.try_push_str(text));
Ok(())
}();
assert!(t.is_err());
@@ -347,7 +355,7 @@ fn test_string_from_bytes() {
fn test_string_clone() {
let text = "hi";
let mut s = ArrayString::<[_; 4]>::new();
s.push_str("abcd").unwrap();
s.push_str("abcd");
let t = ArrayString::<[_; 4]>::from(text).unwrap();
s.clone_from(&t);
assert_eq!(&t, &s);
@@ -358,42 +366,44 @@ fn test_string_push() {
let text = "abcαβγ";
let mut s = ArrayString::<[_; 8]>::new();
for c in text.chars() {
if let Err(_) = s.push(c) {
if let Err(_) = s.try_push(c) {
break;
}
}
assert_eq!("abcαβ", &s[..]);
s.push('x').ok();
s.push('x');
assert_eq!("abcαβx", &s[..]);
assert!(s.push('x').is_err());
assert!(s.try_push('x').is_err());
}
#[test]
fn test_insert_at_length() {
let mut v = ArrayVec::<[_; 8]>::new();
let result1 = v.insert(0, "a");
let result2 = v.insert(1, "b");
assert!(result1.is_none() && result2.is_none());
let result1 = v.try_insert(0, "a");
let result2 = v.try_insert(1, "b");
assert!(result1.is_ok() && result2.is_ok());
assert_eq!(&v[..], &["a", "b"]);
}
#[should_panic]
#[test]
fn test_insert_out_of_bounds() {
let mut v = ArrayVec::<[_; 8]>::new();
let result = v.insert(1, "test");
assert_eq!(result, Some("test"));
assert_eq!(v.len(), 0);
let mut u = ArrayVec::from([1, 2, 3, 4]);
let ret = u.insert(3, 99);
assert_eq!(&u[..], &[1, 2, 3, 99]);
assert_eq!(ret, Some(4));
let ret = u.insert(4, 77);
assert_eq!(&u[..], &[1, 2, 3, 99]);
assert_eq!(ret, Some(77));
let _ = v.try_insert(1, "test");
}
/*
* insert that pushes out the last
let mut u = ArrayVec::from([1, 2, 3, 4]);
let ret = u.try_insert(3, 99);
assert_eq!(&u[..], &[1, 2, 3, 99]);
assert_matches!(ret, Err(_));
let ret = u.try_insert(4, 77);
assert_eq!(&u[..], &[1, 2, 3, 99]);
assert_matches!(ret, Err(_));
*/
#[test]
fn test_drop_in_insert() {
use std::cell::Cell;
@@ -416,11 +426,27 @@ fn test_drop_in_insert() {
array.push(Bump(flag));
array.insert(0, Bump(flag));
assert_eq!(flag.get(), 0);
let ret = array.insert(1, Bump(flag));
let ret = array.try_insert(1, Bump(flag));
assert_eq!(flag.get(), 0);
assert!(ret.is_some());
assert_matches!(ret, Err(_));
drop(ret);
assert_eq!(flag.get(), 1);
}
assert_eq!(flag.get(), 3);
}
#[test]
fn test_pop_at() {
let mut v = ArrayVec::<[String; 4]>::new();
let s = String::from;
v.push(s("a"));
v.push(s("b"));
v.push(s("c"));
v.push(s("d"));
assert_eq!(v.pop_at(4), None);
assert_eq!(v.pop_at(1), Some(s("b")));
assert_eq!(v.pop_at(1), Some(s("c")));
assert_eq!(v.pop_at(2), None);
assert_eq!(&v[..], &["a", "d"]);
}