1 use std::borrow::Borrow; 2 use std::cmp; 3 use std::fmt; 4 use std::hash::{Hash, Hasher}; 5 use std::ptr; 6 use std::ops::{Deref, DerefMut}; 7 use std::str; 8 use std::str::FromStr; 9 use std::str::Utf8Error; 10 use std::slice; 11 12 use crate::array::Array; 13 use crate::array::Index; 14 use crate::CapacityError; 15 use crate::char::encode_utf8; 16 17 #[cfg(feature="serde")] 18 use serde::{Serialize, Deserialize, Serializer, Deserializer}; 19 20 use super::MaybeUninit as MaybeUninitCopy; 21 22 /// A string with a fixed capacity. 23 /// 24 /// The `ArrayString` is a string backed by a fixed size array. It keeps track 25 /// of its length. 26 /// 27 /// The string is a contiguous value that you can store directly on the stack 28 /// if needed. 29 #[derive(Copy)] 30 pub struct ArrayString<A> 31 where A: Array<Item=u8> + Copy 32 { 33 xs: MaybeUninitCopy<A>, 34 len: A::Index, 35 } 36 37 impl<A> Default for ArrayString<A> 38 where A: Array<Item=u8> + Copy 39 { 40 /// Return an empty `ArrayString` default() -> ArrayString<A>41 fn default() -> ArrayString<A> { 42 ArrayString::new() 43 } 44 } 45 46 impl<A> ArrayString<A> 47 where A: Array<Item=u8> + Copy 48 { 49 /// Create a new empty `ArrayString`. 50 /// 51 /// Capacity is inferred from the type parameter. 52 /// 53 /// ``` 54 /// use arrayvec::ArrayString; 55 /// 56 /// let mut string = ArrayString::<[_; 16]>::new(); 57 /// string.push_str("foo"); 58 /// assert_eq!(&string[..], "foo"); 59 /// assert_eq!(string.capacity(), 16); 60 /// ``` 61 #[cfg(not(feature="unstable-const-fn"))] new() -> ArrayString<A>62 pub fn new() -> ArrayString<A> { 63 unsafe { 64 ArrayString { 65 xs: MaybeUninitCopy::uninitialized(), 66 len: Index::ZERO, 67 } 68 } 69 } 70 71 #[cfg(feature="unstable-const-fn")] new() -> ArrayString<A>72 pub const fn new() -> ArrayString<A> { 73 unsafe { 74 ArrayString { 75 xs: MaybeUninitCopy::uninitialized(), 76 len: Index::ZERO, 77 } 78 } 79 } 80 81 /// Return the length of the string. 82 #[inline] len(&self) -> usize83 pub fn len(&self) -> usize { self.len.to_usize() } 84 85 /// Returns whether the string is empty. 86 #[inline] is_empty(&self) -> bool87 pub fn is_empty(&self) -> bool { self.len() == 0 } 88 89 /// Create a new `ArrayString` from a `str`. 90 /// 91 /// Capacity is inferred from the type parameter. 92 /// 93 /// **Errors** if the backing array is not large enough to fit the string. 94 /// 95 /// ``` 96 /// use arrayvec::ArrayString; 97 /// 98 /// let mut string = ArrayString::<[_; 3]>::from("foo").unwrap(); 99 /// assert_eq!(&string[..], "foo"); 100 /// assert_eq!(string.len(), 3); 101 /// assert_eq!(string.capacity(), 3); 102 /// ``` from(s: &str) -> Result<Self, CapacityError<&str>>103 pub fn from(s: &str) -> Result<Self, CapacityError<&str>> { 104 let mut arraystr = Self::new(); 105 arraystr.try_push_str(s)?; 106 Ok(arraystr) 107 } 108 109 /// Create a new `ArrayString` from a byte string literal. 110 /// 111 /// **Errors** if the byte string literal is not valid UTF-8. 112 /// 113 /// ``` 114 /// use arrayvec::ArrayString; 115 /// 116 /// let string = ArrayString::from_byte_string(b"hello world").unwrap(); 117 /// ``` from_byte_string(b: &A) -> Result<Self, Utf8Error>118 pub fn from_byte_string(b: &A) -> Result<Self, Utf8Error> { 119 let len = str::from_utf8(b.as_slice())?.len(); 120 debug_assert_eq!(len, A::CAPACITY); 121 Ok(ArrayString { 122 xs: MaybeUninitCopy::from(*b), 123 len: Index::from(A::CAPACITY), 124 }) 125 } 126 127 /// Return the capacity of the `ArrayString`. 128 /// 129 /// ``` 130 /// use arrayvec::ArrayString; 131 /// 132 /// let string = ArrayString::<[_; 3]>::new(); 133 /// assert_eq!(string.capacity(), 3); 134 /// ``` 135 #[inline(always)] capacity(&self) -> usize136 pub fn capacity(&self) -> usize { A::CAPACITY } 137 138 /// Return if the `ArrayString` is completely filled. 139 /// 140 /// ``` 141 /// use arrayvec::ArrayString; 142 /// 143 /// let mut string = ArrayString::<[_; 1]>::new(); 144 /// assert!(!string.is_full()); 145 /// string.push_str("A"); 146 /// assert!(string.is_full()); 147 /// ``` is_full(&self) -> bool148 pub fn is_full(&self) -> bool { self.len() == self.capacity() } 149 150 /// Adds the given char to the end of the string. 151 /// 152 /// ***Panics*** if the backing array is not large enough to fit the additional char. 153 /// 154 /// ``` 155 /// use arrayvec::ArrayString; 156 /// 157 /// let mut string = ArrayString::<[_; 2]>::new(); 158 /// 159 /// string.push('a'); 160 /// string.push('b'); 161 /// 162 /// assert_eq!(&string[..], "ab"); 163 /// ``` push(&mut self, c: char)164 pub fn push(&mut self, c: char) { 165 self.try_push(c).unwrap(); 166 } 167 168 /// Adds the given char to the end of the string. 169 /// 170 /// Returns `Ok` if the push succeeds. 171 /// 172 /// **Errors** if the backing array is not large enough to fit the additional char. 173 /// 174 /// ``` 175 /// use arrayvec::ArrayString; 176 /// 177 /// let mut string = ArrayString::<[_; 2]>::new(); 178 /// 179 /// string.try_push('a').unwrap(); 180 /// string.try_push('b').unwrap(); 181 /// let overflow = string.try_push('c'); 182 /// 183 /// assert_eq!(&string[..], "ab"); 184 /// assert_eq!(overflow.unwrap_err().element(), 'c'); 185 /// ``` try_push(&mut self, c: char) -> Result<(), CapacityError<char>>186 pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> { 187 let len = self.len(); 188 unsafe { 189 let ptr = self.xs.ptr_mut().add(len); 190 let remaining_cap = self.capacity() - len; 191 match encode_utf8(c, ptr, remaining_cap) { 192 Ok(n) => { 193 self.set_len(len + n); 194 Ok(()) 195 } 196 Err(_) => Err(CapacityError::new(c)), 197 } 198 } 199 } 200 201 /// Adds the given string slice to the end of the string. 202 /// 203 /// ***Panics*** if the backing array is not large enough to fit the string. 204 /// 205 /// ``` 206 /// use arrayvec::ArrayString; 207 /// 208 /// let mut string = ArrayString::<[_; 2]>::new(); 209 /// 210 /// string.push_str("a"); 211 /// string.push_str("d"); 212 /// 213 /// assert_eq!(&string[..], "ad"); 214 /// ``` push_str(&mut self, s: &str)215 pub fn push_str(&mut self, s: &str) { 216 self.try_push_str(s).unwrap() 217 } 218 219 /// Adds the given string slice to the end of the string. 220 /// 221 /// Returns `Ok` if the push succeeds. 222 /// 223 /// **Errors** if the backing array is not large enough to fit the string. 224 /// 225 /// ``` 226 /// use arrayvec::ArrayString; 227 /// 228 /// let mut string = ArrayString::<[_; 2]>::new(); 229 /// 230 /// string.try_push_str("a").unwrap(); 231 /// let overflow1 = string.try_push_str("bc"); 232 /// string.try_push_str("d").unwrap(); 233 /// let overflow2 = string.try_push_str("ef"); 234 /// 235 /// assert_eq!(&string[..], "ad"); 236 /// assert_eq!(overflow1.unwrap_err().element(), "bc"); 237 /// assert_eq!(overflow2.unwrap_err().element(), "ef"); 238 /// ``` try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>>239 pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> { 240 if s.len() > self.capacity() - self.len() { 241 return Err(CapacityError::new(s)); 242 } 243 unsafe { 244 let dst = self.xs.ptr_mut().add(self.len()); 245 let src = s.as_ptr(); 246 ptr::copy_nonoverlapping(src, dst, s.len()); 247 let newl = self.len() + s.len(); 248 self.set_len(newl); 249 } 250 Ok(()) 251 } 252 253 /// Removes the last character from the string and returns it. 254 /// 255 /// Returns `None` if this `ArrayString` is empty. 256 /// 257 /// ``` 258 /// use arrayvec::ArrayString; 259 /// 260 /// let mut s = ArrayString::<[_; 3]>::from("foo").unwrap(); 261 /// 262 /// assert_eq!(s.pop(), Some('o')); 263 /// assert_eq!(s.pop(), Some('o')); 264 /// assert_eq!(s.pop(), Some('f')); 265 /// 266 /// assert_eq!(s.pop(), None); 267 /// ``` pop(&mut self) -> Option<char>268 pub fn pop(&mut self) -> Option<char> { 269 let ch = match self.chars().rev().next() { 270 Some(ch) => ch, 271 None => return None, 272 }; 273 let new_len = self.len() - ch.len_utf8(); 274 unsafe { 275 self.set_len(new_len); 276 } 277 Some(ch) 278 } 279 280 /// Shortens this `ArrayString` to the specified length. 281 /// 282 /// If `new_len` is greater than the string’s current length, this has no 283 /// effect. 284 /// 285 /// ***Panics*** if `new_len` does not lie on a `char` boundary. 286 /// 287 /// ``` 288 /// use arrayvec::ArrayString; 289 /// 290 /// let mut string = ArrayString::<[_; 6]>::from("foobar").unwrap(); 291 /// string.truncate(3); 292 /// assert_eq!(&string[..], "foo"); 293 /// string.truncate(4); 294 /// assert_eq!(&string[..], "foo"); 295 /// ``` truncate(&mut self, new_len: usize)296 pub fn truncate(&mut self, new_len: usize) { 297 if new_len <= self.len() { 298 assert!(self.is_char_boundary(new_len)); 299 unsafe { 300 // In libstd truncate is called on the underlying vector, 301 // which in turns drops each element. 302 // As we know we don't have to worry about Drop, 303 // we can just set the length (a la clear.) 304 self.set_len(new_len); 305 } 306 } 307 } 308 309 /// Removes a `char` from this `ArrayString` at a byte position and returns it. 310 /// 311 /// This is an `O(n)` operation, as it requires copying every element in the 312 /// array. 313 /// 314 /// ***Panics*** if `idx` is larger than or equal to the `ArrayString`’s length, 315 /// or if it does not lie on a `char` boundary. 316 /// 317 /// ``` 318 /// use arrayvec::ArrayString; 319 /// 320 /// let mut s = ArrayString::<[_; 3]>::from("foo").unwrap(); 321 /// 322 /// assert_eq!(s.remove(0), 'f'); 323 /// assert_eq!(s.remove(1), 'o'); 324 /// assert_eq!(s.remove(0), 'o'); 325 /// ``` remove(&mut self, idx: usize) -> char326 pub fn remove(&mut self, idx: usize) -> char { 327 let ch = match self[idx..].chars().next() { 328 Some(ch) => ch, 329 None => panic!("cannot remove a char from the end of a string"), 330 }; 331 332 let next = idx + ch.len_utf8(); 333 let len = self.len(); 334 unsafe { 335 ptr::copy(self.xs.ptr().add(next), 336 self.xs.ptr_mut().add(idx), 337 len - next); 338 self.set_len(len - (next - idx)); 339 } 340 ch 341 } 342 343 /// Make the string empty. clear(&mut self)344 pub fn clear(&mut self) { 345 unsafe { 346 self.set_len(0); 347 } 348 } 349 350 /// Set the strings’s length. 351 /// 352 /// This function is `unsafe` because it changes the notion of the 353 /// number of “valid” bytes in the string. Use with care. 354 /// 355 /// This method uses *debug assertions* to check the validity of `length` 356 /// and may use other debug assertions. set_len(&mut self, length: usize)357 pub unsafe fn set_len(&mut self, length: usize) { 358 debug_assert!(length <= self.capacity()); 359 self.len = Index::from(length); 360 } 361 362 /// Return a string slice of the whole `ArrayString`. as_str(&self) -> &str363 pub fn as_str(&self) -> &str { 364 self 365 } 366 } 367 368 impl<A> Deref for ArrayString<A> 369 where A: Array<Item=u8> + Copy 370 { 371 type Target = str; 372 #[inline] deref(&self) -> &str373 fn deref(&self) -> &str { 374 unsafe { 375 let sl = slice::from_raw_parts(self.xs.ptr(), self.len.to_usize()); 376 str::from_utf8_unchecked(sl) 377 } 378 } 379 } 380 381 impl<A> DerefMut for ArrayString<A> 382 where A: Array<Item=u8> + Copy 383 { 384 #[inline] deref_mut(&mut self) -> &mut str385 fn deref_mut(&mut self) -> &mut str { 386 unsafe { 387 let sl = slice::from_raw_parts_mut(self.xs.ptr_mut(), self.len.to_usize()); 388 str::from_utf8_unchecked_mut(sl) 389 } 390 } 391 } 392 393 impl<A> PartialEq for ArrayString<A> 394 where A: Array<Item=u8> + Copy 395 { eq(&self, rhs: &Self) -> bool396 fn eq(&self, rhs: &Self) -> bool { 397 **self == **rhs 398 } 399 } 400 401 impl<A> PartialEq<str> for ArrayString<A> 402 where A: Array<Item=u8> + Copy 403 { eq(&self, rhs: &str) -> bool404 fn eq(&self, rhs: &str) -> bool { 405 &**self == rhs 406 } 407 } 408 409 impl<A> PartialEq<ArrayString<A>> for str 410 where A: Array<Item=u8> + Copy 411 { eq(&self, rhs: &ArrayString<A>) -> bool412 fn eq(&self, rhs: &ArrayString<A>) -> bool { 413 self == &**rhs 414 } 415 } 416 417 impl<A> Eq for ArrayString<A> 418 where A: Array<Item=u8> + Copy 419 { } 420 421 impl<A> Hash for ArrayString<A> 422 where A: Array<Item=u8> + Copy 423 { hash<H: Hasher>(&self, h: &mut H)424 fn hash<H: Hasher>(&self, h: &mut H) { 425 (**self).hash(h) 426 } 427 } 428 429 impl<A> Borrow<str> for ArrayString<A> 430 where A: Array<Item=u8> + Copy 431 { borrow(&self) -> &str432 fn borrow(&self) -> &str { self } 433 } 434 435 impl<A> AsRef<str> for ArrayString<A> 436 where A: Array<Item=u8> + Copy 437 { as_ref(&self) -> &str438 fn as_ref(&self) -> &str { self } 439 } 440 441 impl<A> fmt::Debug for ArrayString<A> 442 where A: Array<Item=u8> + Copy 443 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result444 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } 445 } 446 447 impl<A> fmt::Display for ArrayString<A> 448 where A: Array<Item=u8> + Copy 449 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result450 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } 451 } 452 453 /// `Write` appends written data to the end of the string. 454 impl<A> fmt::Write for ArrayString<A> 455 where A: Array<Item=u8> + Copy 456 { write_char(&mut self, c: char) -> fmt::Result457 fn write_char(&mut self, c: char) -> fmt::Result { 458 self.try_push(c).map_err(|_| fmt::Error) 459 } 460 write_str(&mut self, s: &str) -> fmt::Result461 fn write_str(&mut self, s: &str) -> fmt::Result { 462 self.try_push_str(s).map_err(|_| fmt::Error) 463 } 464 } 465 466 impl<A> Clone for ArrayString<A> 467 where A: Array<Item=u8> + Copy 468 { clone(&self) -> ArrayString<A>469 fn clone(&self) -> ArrayString<A> { 470 *self 471 } clone_from(&mut self, rhs: &Self)472 fn clone_from(&mut self, rhs: &Self) { 473 // guaranteed to fit due to types matching. 474 self.clear(); 475 self.try_push_str(rhs).ok(); 476 } 477 } 478 479 impl<A> PartialOrd for ArrayString<A> 480 where A: Array<Item=u8> + Copy 481 { partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering>482 fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> { 483 (**self).partial_cmp(&**rhs) 484 } lt(&self, rhs: &Self) -> bool485 fn lt(&self, rhs: &Self) -> bool { **self < **rhs } le(&self, rhs: &Self) -> bool486 fn le(&self, rhs: &Self) -> bool { **self <= **rhs } gt(&self, rhs: &Self) -> bool487 fn gt(&self, rhs: &Self) -> bool { **self > **rhs } ge(&self, rhs: &Self) -> bool488 fn ge(&self, rhs: &Self) -> bool { **self >= **rhs } 489 } 490 491 impl<A> PartialOrd<str> for ArrayString<A> 492 where A: Array<Item=u8> + Copy 493 { partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering>494 fn partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering> { 495 (**self).partial_cmp(rhs) 496 } lt(&self, rhs: &str) -> bool497 fn lt(&self, rhs: &str) -> bool { &**self < rhs } le(&self, rhs: &str) -> bool498 fn le(&self, rhs: &str) -> bool { &**self <= rhs } gt(&self, rhs: &str) -> bool499 fn gt(&self, rhs: &str) -> bool { &**self > rhs } ge(&self, rhs: &str) -> bool500 fn ge(&self, rhs: &str) -> bool { &**self >= rhs } 501 } 502 503 impl<A> PartialOrd<ArrayString<A>> for str 504 where A: Array<Item=u8> + Copy 505 { partial_cmp(&self, rhs: &ArrayString<A>) -> Option<cmp::Ordering>506 fn partial_cmp(&self, rhs: &ArrayString<A>) -> Option<cmp::Ordering> { 507 self.partial_cmp(&**rhs) 508 } lt(&self, rhs: &ArrayString<A>) -> bool509 fn lt(&self, rhs: &ArrayString<A>) -> bool { self < &**rhs } le(&self, rhs: &ArrayString<A>) -> bool510 fn le(&self, rhs: &ArrayString<A>) -> bool { self <= &**rhs } gt(&self, rhs: &ArrayString<A>) -> bool511 fn gt(&self, rhs: &ArrayString<A>) -> bool { self > &**rhs } ge(&self, rhs: &ArrayString<A>) -> bool512 fn ge(&self, rhs: &ArrayString<A>) -> bool { self >= &**rhs } 513 } 514 515 impl<A> Ord for ArrayString<A> 516 where A: Array<Item=u8> + Copy 517 { cmp(&self, rhs: &Self) -> cmp::Ordering518 fn cmp(&self, rhs: &Self) -> cmp::Ordering { 519 (**self).cmp(&**rhs) 520 } 521 } 522 523 impl<A> FromStr for ArrayString<A> 524 where A: Array<Item=u8> + Copy 525 { 526 type Err = CapacityError; 527 from_str(s: &str) -> Result<Self, Self::Err>528 fn from_str(s: &str) -> Result<Self, Self::Err> { 529 Self::from(s).map_err(CapacityError::simplify) 530 } 531 } 532 533 #[cfg(feature="serde")] 534 /// Requires crate feature `"serde"` 535 impl<A> Serialize for ArrayString<A> 536 where A: Array<Item=u8> + Copy 537 { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer538 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 539 where S: Serializer 540 { 541 serializer.serialize_str(&*self) 542 } 543 } 544 545 #[cfg(feature="serde")] 546 /// Requires crate feature `"serde"` 547 impl<'de, A> Deserialize<'de> for ArrayString<A> 548 where A: Array<Item=u8> + Copy 549 { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>550 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 551 where D: Deserializer<'de> 552 { 553 use serde::de::{self, Visitor}; 554 use std::marker::PhantomData; 555 556 struct ArrayStringVisitor<A: Array<Item=u8>>(PhantomData<A>); 557 558 impl<'de, A: Copy + Array<Item=u8>> Visitor<'de> for ArrayStringVisitor<A> { 559 type Value = ArrayString<A>; 560 561 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 562 write!(formatter, "a string no more than {} bytes long", A::CAPACITY) 563 } 564 565 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> 566 where E: de::Error, 567 { 568 ArrayString::from(v).map_err(|_| E::invalid_length(v.len(), &self)) 569 } 570 571 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> 572 where E: de::Error, 573 { 574 let s = str::from_utf8(v).map_err(|_| E::invalid_value(de::Unexpected::Bytes(v), &self))?; 575 576 ArrayString::from(s).map_err(|_| E::invalid_length(s.len(), &self)) 577 } 578 } 579 580 deserializer.deserialize_str(ArrayStringVisitor::<A>(PhantomData)) 581 } 582 } 583