diff --git a/.travis.yml b/.travis.yml index bbfd88c..d1722b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: rust sudo: false matrix: include: + - rust: 1.2.0 - rust: stable - rust: beta - rust: nightly diff --git a/src/array_string.rs b/src/array_string.rs index 154b74c..a39fbcc 100644 --- a/src/array_string.rs +++ b/src/array_string.rs @@ -1,7 +1,8 @@ use std::borrow::Borrow; use std::fmt; use std::hash::{Hash, Hasher}; -use std::ops::Deref; +use std::mem; +use std::ops::{Deref, DerefMut}; use std::str; use std::slice; @@ -99,7 +100,7 @@ impl> ArrayString { pub fn push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> { use std::io::Write; - if self.len() + s.len() > self.capacity() { + if s.len() > self.capacity() - self.len() { return Err(CapacityError::new(s)); } unsafe { @@ -142,6 +143,17 @@ impl> Deref for ArrayString { } } +impl> DerefMut for ArrayString { + #[inline] + fn deref_mut(&mut self) -> &mut str { + unsafe { + let sl = slice::from_raw_parts_mut(self.xs.as_mut_ptr(), self.len.to_usize()); + // FIXME: Nothing but transmute to do this right now + mem::transmute(sl) + } + } +} + impl> PartialEq for ArrayString { fn eq(&self, rhs: &Self) -> bool { **self == **rhs diff --git a/src/lib.rs b/src/lib.rs index ea20055..ad576c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,9 +57,7 @@ pub struct ArrayVec { impl Drop for ArrayVec { fn drop(&mut self) { - // clear all elements - while let Some(_) = self.pop() { - } + self.clear(); // NoDrop inhibits array's drop // panic safety: NoDrop::drop will trigger on panic, so the inner @@ -340,6 +338,12 @@ impl ArrayVec { } } } + + /// Dispose of `self` without the overwriting that is needed in Drop. + pub fn dispose(mut self) { + self.clear(); + mem::forget(self); + } } impl Deref for ArrayVec { @@ -701,7 +705,7 @@ impl> io::Write for ArrayVec { /// Error value indicating insufficient capacity #[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)] -pub struct CapacityError { +pub struct CapacityError { element: T, } @@ -716,6 +720,11 @@ impl CapacityError { 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"; diff --git a/tests/tests.rs b/tests/tests.rs index 3dd24bd..b0b256d 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -283,6 +283,12 @@ fn test_string() { assert!(t.push_str(text).is_err()); assert_eq!(&t, ""); + t.push_str("ab").unwrap(); + // DerefMut + let tmut: &mut str = &mut t; + assert_eq!(tmut, "ab"); + + // Test Error trait / try let t = || -> Result<(), Box> { let mut t = ArrayString::<[_; 2]>::new();