@@ -15,14 +15,11 @@ pub unsafe trait Array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Index : PartialEq + Copy {
|
pub trait Index : PartialEq + Copy {
|
||||||
fn zero() -> Self;
|
|
||||||
fn to_usize(self) -> usize;
|
fn to_usize(self) -> usize;
|
||||||
fn from(usize) -> Self;
|
fn from(usize) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index for u8 {
|
impl Index for u8 {
|
||||||
#[inline(always)]
|
|
||||||
fn zero() -> Self { 0 }
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_usize(self) -> usize { self as usize }
|
fn to_usize(self) -> usize { self as usize }
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -30,8 +27,6 @@ impl Index for u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Index for u16 {
|
impl Index for u16 {
|
||||||
#[inline(always)]
|
|
||||||
fn zero() -> Self { 0 }
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_usize(self) -> usize { self as usize }
|
fn to_usize(self) -> usize { self as usize }
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|||||||
+36
-15
@@ -1,6 +1,6 @@
|
|||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
@@ -22,14 +22,6 @@ pub struct ArrayString<A: Array<Item=u8>> {
|
|||||||
len: A::Index,
|
len: A::Index,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn new_array<A: Array<Item=u8>>() -> A {
|
|
||||||
// Note: Returning an uninitialized value here only works
|
|
||||||
// if we can be sure the data is never used. The nullable pointer
|
|
||||||
// inside enum optimization conflicts with this this for example,
|
|
||||||
// so we need to be extra careful. See `NoDrop` enum.
|
|
||||||
mem::uninitialized()
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A: Array<Item=u8>> ArrayString<A> {
|
impl<A: Array<Item=u8>> ArrayString<A> {
|
||||||
/// Create a new empty `ArrayString`.
|
/// Create a new empty `ArrayString`.
|
||||||
///
|
///
|
||||||
@@ -46,7 +38,7 @@ impl<A: Array<Item=u8>> ArrayString<A> {
|
|||||||
pub fn new() -> ArrayString<A> {
|
pub fn new() -> ArrayString<A> {
|
||||||
unsafe {
|
unsafe {
|
||||||
ArrayString {
|
ArrayString {
|
||||||
xs: new_array(),
|
xs: ::new_array(),
|
||||||
len: Index::from(0),
|
len: Index::from(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,7 +70,7 @@ impl<A: Array<Item=u8>> ArrayString<A> {
|
|||||||
/// let overflow = string.push('c');
|
/// let overflow = string.push('c');
|
||||||
///
|
///
|
||||||
/// assert_eq!(&string[..], "ab");
|
/// assert_eq!(&string[..], "ab");
|
||||||
/// assert_eq!(overflow.err().map(|e| e.element), Some('c'));
|
/// assert_eq!(overflow.unwrap_err().element(), 'c');
|
||||||
/// ```
|
/// ```
|
||||||
pub fn push(&mut self, c: char) -> Result<(), CapacityError<char>> {
|
pub fn push(&mut self, c: char) -> Result<(), CapacityError<char>> {
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
@@ -101,8 +93,8 @@ impl<A: Array<Item=u8>> ArrayString<A> {
|
|||||||
/// let overflow2 = string.push_str("ef");
|
/// let overflow2 = string.push_str("ef");
|
||||||
///
|
///
|
||||||
/// assert_eq!(&string[..], "ad");
|
/// assert_eq!(&string[..], "ad");
|
||||||
/// assert_eq!(overflow1.err().map(|e| e.element), Some("bc"));
|
/// assert_eq!(overflow1.unwrap_err().element(), "bc");
|
||||||
/// assert_eq!(overflow2.err().map(|e| e.element), Some("ef"));
|
/// assert_eq!(overflow2.unwrap_err().element(), "ef");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
|
pub fn push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
@@ -150,6 +142,32 @@ impl<A: Array<Item=u8>> Deref for ArrayString<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A: Array<Item=u8>> PartialEq for ArrayString<A> {
|
||||||
|
fn eq(&self, rhs: &Self) -> bool {
|
||||||
|
**self == **rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Array<Item=u8>> PartialEq<str> for ArrayString<A> {
|
||||||
|
fn eq(&self, rhs: &str) -> bool {
|
||||||
|
&**self == rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Array<Item=u8>> PartialEq<ArrayString<A>> for str {
|
||||||
|
fn eq(&self, rhs: &ArrayString<A>) -> bool {
|
||||||
|
self == &**rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Array<Item=u8>> Eq for ArrayString<A> { }
|
||||||
|
|
||||||
|
impl<A: Array<Item=u8>> Hash for ArrayString<A> {
|
||||||
|
fn hash<H: Hasher>(&self, h: &mut H) {
|
||||||
|
(**self).hash(h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<A: Array<Item=u8>> Borrow<str> for ArrayString<A> {
|
impl<A: Array<Item=u8>> Borrow<str> for ArrayString<A> {
|
||||||
fn borrow(&self) -> &str { self }
|
fn borrow(&self) -> &str { self }
|
||||||
}
|
}
|
||||||
@@ -158,7 +176,11 @@ impl<A: Array<Item=u8>> AsRef<str> for ArrayString<A> {
|
|||||||
fn as_ref(&self) -> &str { self }
|
fn as_ref(&self) -> &str { self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: Array<Item=u8>> fmt::Debug for ArrayString<A> where A::Item: fmt::Debug {
|
impl<A: Array<Item=u8>> fmt::Debug for ArrayString<A> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Array<Item=u8>> fmt::Display for ArrayString<A> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,4 +196,3 @@ impl<A: Array<Item=u8> + Copy> Clone for ArrayString<A> {
|
|||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-5
@@ -36,19 +36,23 @@ unsafe fn new_array<A: Array>() -> A {
|
|||||||
mem::uninitialized()
|
mem::uninitialized()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Error value indicating insufficient capacity
|
||||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
pub struct CapacityError<T> {
|
pub struct CapacityError<T> {
|
||||||
_unused: (),
|
element: T,
|
||||||
pub element: T,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> CapacityError<T> {
|
impl<T> CapacityError<T> {
|
||||||
fn new(element: T) -> CapacityError<T> {
|
fn new(element: T) -> CapacityError<T> {
|
||||||
CapacityError {
|
CapacityError {
|
||||||
_unused: (),
|
|
||||||
element: element,
|
element: element,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract the overflowing element
|
||||||
|
pub fn element(self) -> T {
|
||||||
|
self.element
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A vector with a fixed capacity.
|
/// A vector with a fixed capacity.
|
||||||
@@ -96,7 +100,7 @@ impl<A: Array> ArrayVec<A> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn new() -> ArrayVec<A> {
|
pub fn new() -> ArrayVec<A> {
|
||||||
unsafe {
|
unsafe {
|
||||||
ArrayVec { xs: NoDrop::new(new_array()), len: Index::zero() }
|
ArrayVec { xs: NoDrop::new(new_array()), len: Index::from(0) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +444,7 @@ impl<A: Array> IntoIterator for ArrayVec<A> {
|
|||||||
type Item = A::Item;
|
type Item = A::Item;
|
||||||
type IntoIter = IntoIter<A>;
|
type IntoIter = IntoIter<A>;
|
||||||
fn into_iter(self) -> IntoIter<A> {
|
fn into_iter(self) -> IntoIter<A> {
|
||||||
IntoIter { index: Index::zero(), v: self, }
|
IntoIter { index: Index::from(0), v: self, }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
extern crate arrayvec;
|
extern crate arrayvec;
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
|
use arrayvec::ArrayString;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() {
|
fn test_simple() {
|
||||||
@@ -260,3 +263,21 @@ fn test_write() {
|
|||||||
assert_eq!(r, 5);
|
assert_eq!(r, 5);
|
||||||
assert_eq!(&v[..], &[1, 2, 3, 9, 9, 9, 9, 9]);
|
assert_eq!(&v[..], &[1, 2, 3, 9, 9, 9, 9, 9]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_string() {
|
||||||
|
let text = "hello world";
|
||||||
|
let mut s = ArrayString::<[_; 16]>::new();
|
||||||
|
s.push_str(text).unwrap();
|
||||||
|
assert_eq!(&s, text);
|
||||||
|
assert_eq!(text, &s);
|
||||||
|
|
||||||
|
// Make sure Hash / Eq / Borrow match up so we can use HashMap
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert(s, 1);
|
||||||
|
assert_eq!(map[text], 1);
|
||||||
|
|
||||||
|
let mut t = ArrayString::<[_; 2]>::new();
|
||||||
|
assert!(t.push_str(text).is_err());
|
||||||
|
assert_eq!(&t, "");
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user