Sign In

arrayvec

Package Overview
Dependencies
Maintainers
0
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

arrayvec - cargo Package Compare versions

Comparing version
0.3.25
to
0.4.0
+58
src/errors.rs
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)
}
}
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) }
}
#![cfg(feature = "serde-1")]
extern crate arrayvec;
extern crate serde_test;
mod array_vec {
use arrayvec::ArrayVec;
use serde_test::{Token, assert_tokens, assert_de_tokens_error};
#[test]
fn test_ser_de_empty() {
let vec = ArrayVec::<[u32; 0]>::new();
assert_tokens(&vec, &[
Token::Seq { len: Some(0) },
Token::SeqEnd,
]);
}
#[test]
fn test_ser_de() {
let mut vec = ArrayVec::<[u32; 3]>::new();
vec.push(20);
vec.push(55);
vec.push(123);
assert_tokens(&vec, &[
Token::Seq { len: Some(3) },
Token::U32(20),
Token::U32(55),
Token::U32(123),
Token::SeqEnd,
]);
}
#[test]
fn test_de_too_large() {
assert_de_tokens_error::<ArrayVec<[u32; 2]>>(&[
Token::Seq { len: Some(3) },
Token::U32(13),
Token::U32(42),
Token::U32(68),
], "invalid length 3, expected an array with no more than 2 items");
}
}
mod array_string {
use arrayvec::ArrayString;
use serde_test::{Token, assert_tokens, assert_de_tokens_error};
#[test]
fn test_ser_de_empty() {
let string = ArrayString::<[u8; 0]>::new();
assert_tokens(&string, &[
Token::Str(""),
]);
}
#[test]
fn test_ser_de() {
let string = ArrayString::<[u8; 9]>::from("1234 abcd")
.expect("expected exact specified capacity to be enough");
assert_tokens(&string, &[
Token::Str("1234 abcd"),
]);
}
#[test]
fn test_de_too_large() {
assert_de_tokens_error::<ArrayString<[u8; 2]>>(&[
Token::Str("afd")
], "invalid length 3, expected a string no more than 2 bytes long");
}
}
+1
-0

@@ -11,2 +11,3 @@ # Compiled files

# Generated by Cargo
/Cargo.lock
/target/
+4
-3
language: rust
sudo: false
env:
- FEATURES='serde-1'
matrix:
include:
- rust: 1.2.0
- rust: 1.14.0
- rust: stable
env:
- FEATURES="use_generic_array"
- NODEFAULT=1

@@ -19,3 +20,3 @@ - rust: beta

env:
- FEATURES='use_union use_generic_array'
- FEATURES='serde use_union'
- NODROP_FEATURES='use_union'

@@ -22,0 +23,0 @@ branches:

@@ -15,17 +15,18 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "arrayvec"
version = "0.3.25"
version = "0.4.0"
authors = ["bluss"]
description = "A vector with a fixed capacity, it can be stored on the stack too. Implements fixed capacity ArrayVec and ArrayString."
description = "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString."
documentation = "https://docs.rs/arrayvec/"
keywords = ["stack", "vector", "array", "data-structure", "no_std"]
categories = ["data-structures", "no-std"]
license = "MIT/Apache-2.0"
repository = "https://github.com/bluss/arrayvec"
[package.metadata.docs.rs]
features = ["serde-1"]
[package.metadata.release]
no-dev-version = true
[dependencies.generic-array]
version = "0.5.1"
[dependencies.serde]
version = "1.0"
optional = true
[dependencies.nodrop]
version = "0.1.8"
default-features = false

@@ -37,6 +38,15 @@

[dependencies.nodrop]
version = "0.1.8"
default-features = false
[dev-dependencies.serde_test]
version = "1.0"
[dev-dependencies.matches]
version = "0.1"
[features]
use_union = ["nodrop/use_union"]
std = ["odds/std", "nodrop/std"]
default = ["std"]
std = ["odds/std", "nodrop/std"]
use_generic_array = ["generic-array"]
use_union = ["nodrop/use_union"]
serde-1 = ["serde"]

@@ -5,3 +5,3 @@

A vector with fixed capacity. Requires Rust 1.2+.
A vector with fixed capacity.

@@ -26,11 +26,18 @@ Please read the `API documentation here`__

- 0.3.25
- 0.4.0
- Fix future compat warning about raw pointer casts
- Reformed signatures and error handling by @bluss and @tbu-:
- 0.3.24
- ``ArrayVec``'s ``push, insert, remove, swap_remove`` now match ``Vec``'s
corresponding signature and panic on capacity errors where applicable.
- Add fallible methods ``try_push, insert`` and checked methods
``pop_at, swap_pop``.
- Similar changes to ``ArrayString``'s push methods.
- Fix compilation on 16-bit targets. This means, the 65536 array size is not
included on these targets.
- Fix license files so that they are both included (was fixed in 0.4 before)
- Use a local version of the ``RangeArgument`` trait
- Add array sizes 50, 150, 200 by @daboross
- Support serde 1.0 by @daboross
- New method ``.push_unchecked()`` by @niklasf
- ``ArrayString`` implements ``PartialOrd, Ord`` by @tbu-
- Require Rust 1.14

@@ -37,0 +44,0 @@ - 0.3.23

@@ -15,4 +15,8 @@ use std::borrow::Borrow;

use CapacityError;
use errors::PubCrateNew;
use odds::char::encode_utf8;
#[cfg(feature="serde-1")]
use serde::{Serialize, Deserialize, Serializer, Deserializer};
/// A string with a fixed capacity.

@@ -69,3 +73,3 @@ ///

let mut arraystr = Self::new();
try!(arraystr.push_str(s));
arraystr.try_push_str(s)?;
Ok(arraystr)

@@ -86,3 +90,3 @@ }

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());

@@ -119,2 +123,22 @@ Ok(arraystr)

///
/// ***Panics*** if the backing array is not large enough to fit the additional char.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<[_; 2]>::new();
///
/// 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.

@@ -127,5 +151,5 @@ ///

///
/// string.push('a').unwrap();
/// string.push('b').unwrap();
/// let overflow = string.push('c');
/// string.try_push('a').unwrap();
/// string.try_push('b').unwrap();
/// let overflow = string.try_push('c');
///

@@ -135,3 +159,3 @@ /// assert_eq!(&string[..], "ab");

/// ```
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();

@@ -153,2 +177,22 @@ unsafe {

///
/// ***Panics*** if the backing array is not large enough to fit the string.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<[_; 2]>::new();
///
/// 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.

@@ -161,6 +205,6 @@ ///

///
/// string.push_str("a").unwrap();
/// let overflow1 = string.push_str("bc");
/// string.push_str("d").unwrap();
/// let overflow2 = string.push_str("ef");
/// 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");
///

@@ -171,3 +215,3 @@ /// assert_eq!(&string[..], "ad");

/// ```
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() {

@@ -283,6 +327,7 @@ return Err(CapacityError::new(s));

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)
}

@@ -298,3 +343,3 @@ }

self.clear();
self.push_str(rhs).ok();
self.try_push_str(rhs).ok();
}

@@ -338,1 +383,46 @@ }

}
#[cfg(feature="serde-1")]
impl<A: Array<Item=u8>> Serialize for ArrayString<A> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
serializer.serialize_str(&*self)
}
}
#[cfg(feature="serde-1")]
impl<'de, A: Array<Item=u8>> Deserialize<'de> for ArrayString<A> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
use serde::de::{self, Visitor};
use std::marker::PhantomData;
struct ArrayStringVisitor<A: Array<Item=u8>>(PhantomData<A>);
impl<'de, A: Array<Item=u8>> Visitor<'de> for ArrayStringVisitor<A> {
type Value = ArrayString<A>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a string no more than {} bytes long", A::capacity())
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where E: de::Error,
{
ArrayString::from(v).map_err(|_| E::invalid_length(v.len(), &self))
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where E: de::Error,
{
let s = try!(str::from_utf8(v).map_err(|_| E::invalid_value(de::Unexpected::Bytes(v), &self)));
ArrayString::from(s).map_err(|_| E::invalid_length(s.len(), &self))
}
}
deserializer.deserialize_str(ArrayStringVisitor::<A>(PhantomData))
}
}

@@ -35,20 +35,2 @@

#[cfg(feature = "use_generic_array")]
unsafe impl<T, U> Array for ::generic_array::GenericArray<T, U>
where U: ::generic_array::ArrayLength<T>
{
type Item = T;
type Index = usize;
fn as_ptr(&self) -> *const Self::Item {
(**self).as_ptr()
}
fn as_mut_ptr(&mut self) -> *mut Self::Item {
(**self).as_mut_ptr()
}
fn capacity() -> usize {
U::to_usize()
}
}
impl Index for u8 {

@@ -107,7 +89,5 @@ #[inline(always)]

16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 40, 48, 56, 64, 72, 96, 128, 160, 192, 224,);
32, 40, 48, 50, 56, 64, 72, 96, 100, 128, 160, 192, 200, 224,);
fix_array_impl_recursive!(u16, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,);
// This array size doesn't exist on 16-bit
#[cfg(any(target_pointer_width="32", target_pointer_width="64"))]
fix_array_impl_recursive!(u32, 1 << 16,);
+227
-93
//! **arrayvec** provides the types `ArrayVec` and `ArrayString`:
//! array-backed vector and string types, which store their contents inline.
//!
//! The **arrayvec** crate has the following cargo feature flags:
//! The arrayvec package has the following cargo features:
//!
//! - `std`
//! - Optional, enabled by default
//! - Requires Rust 1.6 *to disable*
//! - Use libstd
//! - Use libstd; disable to use `no_std` instead.
//!

@@ -14,18 +13,19 @@ //! - `use_union`

//! - Requires Rust nightly channel
//! - Experimental: This flag uses nightly so it *may break* unexpectedly
//! at some point; since it doesn't change API this flag may also change
//! to do nothing in the future.
//! - Use the unstable feature untagged unions for the internal implementation,
//! which has reduced space overhead
//! which may have reduced space overhead
//!
//! - `use_generic_array`
//! - Optional
//! - Requires Rust stable channel
//! - Depend on generic-array and allow using it just like a fixed
//! size array for ArrayVec storage.
#![doc(html_root_url="https://docs.rs/arrayvec/0.3/")]
//! ## Rust Version
//!
//! This version of arrayvec requires Rust 1.14 or later.
//!
#![doc(html_root_url="https://docs.rs/arrayvec/0.4/")]
#![cfg_attr(not(feature="std"), no_std)]
extern crate odds;
extern crate nodrop;
#[cfg(feature="serde-1")]
extern crate serde;
#[cfg(feature = "use_generic_array")]
extern crate generic_array;
#[cfg(not(feature="std"))]

@@ -51,16 +51,19 @@ extern crate core as std;

use std::io;
#[cfg(feature="std")]
use std::error::Error;
#[cfg(feature="std")]
use std::any::Any; // core but unused
use nodrop::NoDrop;
#[cfg(feature="serde-1")]
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;

@@ -103,2 +106,9 @@

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> {

@@ -161,4 +171,3 @@ /// Create a new empty `ArrayVec`.

///
/// Return `None` if the push succeeds, or and return `Some(` *element* `)`
/// if the vector is full.
/// ***Panics*** if the vector is already full.
///

@@ -172,31 +181,82 @@ /// ```

/// 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() {
let len = self.len();
unsafe {
ptr::write(self.get_unchecked_mut(len), element);
self.set_len(len + 1);
self.push_unchecked(element);
}
None
Ok(())
} else {
Some(element)
Err(CapacityError::new(element))
}
}
/// Insert `element` in position `index`.
/// Push `element` to the end of the vector without checking the capacity.
///
/// Shift up all elements after `index`. If any is pushed out, it is returned.
/// It is up to the caller to ensure the capacity of the vector is
/// sufficiently large.
///
/// Return `None` if no element is shifted out.
/// This method *may* use debug assertions to check that the arrayvec is not 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.
/// ```
/// use arrayvec::ArrayVec;
///
/// let mut array = ArrayVec::<[_; 2]>::new();
///
/// if array.len() + 2 <= array.capacity() {
/// unsafe {
/// array.push_unchecked(1);
/// array.push_unchecked(2);
/// }
/// }
///
/// assert_eq!(&array[..], &[1, 2]);
/// ```
#[inline]
pub unsafe fn push_unchecked(&mut self, element: A::Item) {
let len = self.len();
debug_assert!(len < A::capacity());
ptr::write(self.get_unchecked_mut(len), element);
self.set_len(len + 1);
}
/// Insert `element` at position `index`.
///
/// Shift up all elements after `index`.
///
/// It is an error if the index is greater than the length or if the
/// arrayvec is full.
///
/// ***Panics*** on errors. See `try_result` for fallible version.
///
/// ```
/// use arrayvec::ArrayVec;

@@ -206,16 +266,37 @@ ///

///
/// 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));
}

@@ -228,3 +309,3 @@ let len = self.len();

{
let p: *mut _ = self.get_unchecked_mut(index);
let p = self.get_unchecked_mut(index) as *mut _;
// Shift everything over to make space. (Duplicating the

@@ -239,6 +320,6 @@ // `index`th element into two consecutive places.)

}
ret
Ok(())
}
/// Remove the last element in the vector.
/// Remove the last element in the vector and return it.
///

@@ -272,2 +353,29 @@ /// Return `Some(` *element* `)` if the vector is non-empty, else `None`.

///
/// 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`.

@@ -280,11 +388,11 @@ ///

///
/// 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;
}

@@ -297,4 +405,6 @@ self.swap(index, len - 1);

///
/// 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.
///
/// ```

@@ -305,8 +415,30 @@ /// use arrayvec::ArrayVec;

///
/// 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.
///
/// assert_eq!(array.remove(10), None);
/// This is a checked version of `.remove(index)`. Returns `None` if there
/// is no element at `index`. Otherwise, return the element inside `Some`.
///
/// ```
pub fn remove(&mut self, index: usize) -> Option<A::Item> {
/// use arrayvec::ArrayVec;
///
/// let mut array = ArrayVec::from([1, 2, 3]);
///
/// assert!(array.pop_at(0).is_some());
/// assert_eq!(&array[..], &[2, 3]);
///
/// assert!(array.pop_at(2).is_none());
/// assert!(array.pop_at(10).is_none());
/// ```
pub fn pop_at(&mut self, index: usize) -> Option<A::Item> {
if index >= self.len() {

@@ -360,3 +492,4 @@ None

///
/// May panic if `length` is greater than the capacity.
/// May use debug assertions to check that `length` is not greater than the
/// capacity.
///

@@ -386,3 +519,3 @@ /// This function is `unsafe` because it changes the notion of the

/// 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]);

@@ -694,3 +827,5 @@ /// assert_eq!(&u[..], &[1, 2]);

for elt in iter.into_iter().take(take) {
self.push(elt);
unsafe {
self.push_unchecked(elt);
}
}

@@ -847,46 +982,45 @@ }

/// Error value indicating insufficient capacity
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
pub struct CapacityError<T = ()> {
element: T,
#[cfg(feature="serde-1")]
impl<T: Serialize, A: Array<Item=T>> Serialize for ArrayVec<A> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
serializer.collect_seq(self)
}
}
impl<T> CapacityError<T> {
fn new(element: T) -> CapacityError<T> {
CapacityError {
element: element,
}
}
#[cfg(feature="serde-1")]
impl<'de, T: Deserialize<'de>, A: Array<Item=T>> Deserialize<'de> for ArrayVec<A> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
use serde::de::{Visitor, SeqAccess, Error};
use std::marker::PhantomData;
/// Extract the overflowing element
pub fn element(self) -> T {
self.element
}
struct ArrayVecVisitor<'de, T: Deserialize<'de>, A: Array<Item=T>>(PhantomData<(&'de (), T, A)>);
/// Convert into a `CapacityError` that does not carry an element.
pub fn simplify(self) -> CapacityError {
CapacityError { element: () }
}
}
impl<'de, T: Deserialize<'de>, A: Array<Item=T>> Visitor<'de> for ArrayVecVisitor<'de, T, A> {
type Value = ArrayVec<A>;
const CAPERROR: &'static str = "insufficient capacity";
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "an array with no more than {} items", A::capacity())
}
#[cfg(feature="std")]
/// Requires `features="std"`.
impl<T: Any> Error for CapacityError<T> {
fn description(&self) -> &str {
CAPERROR
}
}
fn visit_seq<SA>(self, mut seq: SA) -> Result<Self::Value, SA::Error>
where SA: SeqAccess<'de>,
{
let mut values = ArrayVec::<A>::new();
impl<T> fmt::Display for CapacityError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", CAPERROR)
}
}
while let Some(value) = try!(seq.next_element()) {
if let Err(_) = values.try_push(value) {
return Err(SA::Error::invalid_length(A::capacity() + 1, &self));
}
}
impl<T> fmt::Debug for CapacityError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: {}", "CapacityError", CAPERROR)
Ok(values)
}
}
deserializer.deserialize_seq(ArrayVecVisitor::<T, A>(PhantomData))
}
}
extern crate arrayvec;
#[macro_use] extern crate matches;

@@ -6,2 +7,3 @@ use arrayvec::ArrayVec;

use std::mem;
use arrayvec::CapacityError;

@@ -34,5 +36,5 @@ use std::collections::HashMap;

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);

@@ -82,3 +84,5 @@ }

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);

@@ -223,4 +227,3 @@ drop(array.pop());

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(_));

@@ -230,11 +233,16 @@ let mut v = ArrayVec::<[_; 3]>::new();

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 { .. }));
}

@@ -307,3 +315,3 @@

let mut s = ArrayString::<[_; 16]>::new();
s.push_str(text).unwrap();
s.try_push_str(text).unwrap();
assert_eq!(&s, text);

@@ -318,6 +326,6 @@ assert_eq!(text, &s);

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

@@ -330,3 +338,3 @@ let tmut: &mut str = &mut t;

let mut t = ArrayString::<[_; 2]>::new();
try!(t.push_str(text));
try!(t.try_push_str(text));
Ok(())

@@ -358,3 +366,3 @@ }();

let mut s = ArrayString::<[_; 4]>::new();
s.push_str("abcd").unwrap();
s.push_str("abcd");
let t = ArrayString::<[_; 4]>::from(text).unwrap();

@@ -370,3 +378,3 @@ s.clone_from(&t);

for c in text.chars() {
if let Err(_) = s.push(c) {
if let Err(_) = s.try_push(c) {
break;

@@ -376,5 +384,5 @@ }

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());
}

@@ -386,23 +394,25 @@

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 _ = v.try_insert(1, "test");
}
/*
* insert that pushes out the last
let mut u = ArrayVec::from([1, 2, 3, 4]);
let ret = u.insert(3, 99);
let ret = u.try_insert(3, 99);
assert_eq!(&u[..], &[1, 2, 3, 99]);
assert_eq!(ret, Some(4));
let ret = u.insert(4, 77);
assert_matches!(ret, Err(_));
let ret = u.try_insert(4, 77);
assert_eq!(&u[..], &[1, 2, 3, 99]);
assert_eq!(ret, Some(77));
}
assert_matches!(ret, Err(_));
*/

@@ -431,5 +441,5 @@ #[test]

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);

@@ -442,2 +452,18 @@ assert_eq!(flag.get(), 1);

#[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"]);
}
#[test]
fn test_sizes() {

@@ -444,0 +470,0 @@ let v = ArrayVec::from([0u8; 1 << 16]);

#![cfg(feature = "use_generic_array")]
extern crate arrayvec;
#[macro_use]
extern crate generic_array;
use arrayvec::ArrayVec;
use generic_array::GenericArray;
use generic_array::typenum::U41;
#[test]
fn test_simple() {
let mut vec: ArrayVec<GenericArray<i32, U41>> = ArrayVec::new();
assert_eq!(vec.len(), 0);
assert_eq!(vec.capacity(), 41);
vec.extend(0..20);
assert_eq!(vec.len(), 20);
assert_eq!(&vec[..5], &[0, 1, 2, 3, 4]);
}

Sorry, the diff of this file is not supported yet