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 /// ``` new() -> ArrayString<A>61 pub fn new() -> ArrayString<A> { 62 unsafe { 63 ArrayString { 64 xs: MaybeUninitCopy::uninitialized(), 65 len: Index::from(0), 66 } 67 } 68 } 69 70 /// Return the length of the string. 71 #[inline] len(&self) -> usize72 pub fn len(&self) -> usize { self.len.to_usize() } 73 74 /// Create a new `ArrayString` from a `str`. 75 /// 76 /// Capacity is inferred from the type parameter. 77 /// 78 /// **Errors** if the backing array is not large enough to fit the string. 79 /// 80 /// ``` 81 /// use arrayvec::ArrayString; 82 /// 83 /// let mut string = ArrayString::<[_; 3]>::from("foo").unwrap(); 84 /// assert_eq!(&string[..], "foo"); 85 /// assert_eq!(string.len(), 3); 86 /// assert_eq!(string.capacity(), 3); 87 /// ``` from(s: &str) -> Result<Self, CapacityError<&str>>88 pub fn from(s: &str) -> Result<Self, CapacityError<&str>> { 89 let mut arraystr = Self::new(); 90 arraystr.try_push_str(s)?; 91 Ok(arraystr) 92 } 93 94 /// Create a new `ArrayString` from a byte string literal. 95 /// 96 /// **Errors** if the byte string literal is not valid UTF-8. 97 /// 98 /// ``` 99 /// use arrayvec::ArrayString; 100 /// 101 /// let string = ArrayString::from_byte_string(b"hello world").unwrap(); 102 /// ``` from_byte_string(b: &A) -> Result<Self, Utf8Error>103 pub fn from_byte_string(b: &A) -> Result<Self, Utf8Error> { 104 let len = str::from_utf8(b.as_slice())?.len(); 105 debug_assert_eq!(len, A::CAPACITY); 106 Ok(ArrayString { 107 xs: MaybeUninitCopy::from(*b), 108 len: Index::from(A::CAPACITY), 109 }) 110 } 111 112 /// Return the capacity of the `ArrayString`. 113 /// 114 /// ``` 115 /// use arrayvec::ArrayString; 116 /// 117 /// let string = ArrayString::<[_; 3]>::new(); 118 /// assert_eq!(string.capacity(), 3); 119 /// ``` 120 #[inline(always)] capacity(&self) -> usize121 pub fn capacity(&self) -> usize { A::CAPACITY } 122 123 /// Return if the `ArrayString` is completely filled. 124 /// 125 /// ``` 126 /// use arrayvec::ArrayString; 127 /// 128 /// let mut string = ArrayString::<[_; 1]>::new(); 129 /// assert!(!string.is_full()); 130 /// string.push_str("A"); 131 /// assert!(string.is_full()); 132 /// ``` is_full(&self) -> bool133 pub fn is_full(&self) -> bool { self.len() == self.capacity() } 134 135 /// Adds the given char to the end of the string. 136 /// 137 /// ***Panics*** if the backing array is not large enough to fit the additional char. 138 /// 139 /// ``` 140 /// use arrayvec::ArrayString; 141 /// 142 /// let mut string = ArrayString::<[_; 2]>::new(); 143 /// 144 /// string.push('a'); 145 /// string.push('b'); 146 /// 147 /// assert_eq!(&string[..], "ab"); 148 /// ``` push(&mut self, c: char)149 pub fn push(&mut self, c: char) { 150 self.try_push(c).unwrap(); 151 } 152 153 /// Adds the given char to the end of the string. 154 /// 155 /// Returns `Ok` if the push succeeds. 156 /// 157 /// **Errors** if the backing array is not large enough to fit the additional char. 158 /// 159 /// ``` 160 /// use arrayvec::ArrayString; 161 /// 162 /// let mut string = ArrayString::<[_; 2]>::new(); 163 /// 164 /// string.try_push('a').unwrap(); 165 /// string.try_push('b').unwrap(); 166 /// let overflow = string.try_push('c'); 167 /// 168 /// assert_eq!(&string[..], "ab"); 169 /// assert_eq!(overflow.unwrap_err().element(), 'c'); 170 /// ``` try_push(&mut self, c: char) -> Result<(), CapacityError<char>>171 pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> { 172 let len = self.len(); 173 unsafe { 174 let ptr = self.xs.ptr_mut().add(len); 175 let remaining_cap = self.capacity() - len; 176 match encode_utf8(c, ptr, remaining_cap) { 177 Ok(n) => { 178 self.set_len(len + n); 179 Ok(()) 180 } 181 Err(_) => Err(CapacityError::new(c)), 182 } 183 } 184 } 185 186 /// Adds the given string slice to the end of the string. 187 /// 188 /// ***Panics*** if the backing array is not large enough to fit the string. 189 /// 190 /// ``` 191 /// use arrayvec::ArrayString; 192 /// 193 /// let mut string = ArrayString::<[_; 2]>::new(); 194 /// 195 /// string.push_str("a"); 196 /// string.push_str("d"); 197 /// 198 /// assert_eq!(&string[..], "ad"); 199 /// ``` push_str(&mut self, s: &str)200 pub fn push_str(&mut self, s: &str) { 201 self.try_push_str(s).unwrap() 202 } 203 204 /// Adds the given string slice to the end of the string. 205 /// 206 /// Returns `Ok` if the push succeeds. 207 /// 208 /// **Errors** if the backing array is not large enough to fit the string. 209 /// 210 /// ``` 211 /// use arrayvec::ArrayString; 212 /// 213 /// let mut string = ArrayString::<[_; 2]>::new(); 214 /// 215 /// string.try_push_str("a").unwrap(); 216 /// let overflow1 = string.try_push_str("bc"); 217 /// string.try_push_str("d").unwrap(); 218 /// let overflow2 = string.try_push_str("ef"); 219 /// 220 /// assert_eq!(&string[..], "ad"); 221 /// assert_eq!(overflow1.unwrap_err().element(), "bc"); 222 /// assert_eq!(overflow2.unwrap_err().element(), "ef"); 223 /// ``` try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>>224 pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> { 225 if s.len() > self.capacity() - self.len() { 226 return Err(CapacityError::new(s)); 227 } 228 unsafe { 229 let dst = self.xs.ptr_mut().offset(self.len() as isize); 230 let src = s.as_ptr(); 231 ptr::copy_nonoverlapping(src, dst, s.len()); 232 let newl = self.len() + s.len(); 233 self.set_len(newl); 234 } 235 Ok(()) 236 } 237 238 /// Removes the last character from the string and returns it. 239 /// 240 /// Returns `None` if this `ArrayString` is empty. 241 /// 242 /// ``` 243 /// use arrayvec::ArrayString; 244 /// 245 /// let mut s = ArrayString::<[_; 3]>::from("foo").unwrap(); 246 /// 247 /// assert_eq!(s.pop(), Some('o')); 248 /// assert_eq!(s.pop(), Some('o')); 249 /// assert_eq!(s.pop(), Some('f')); 250 /// 251 /// assert_eq!(s.pop(), None); 252 /// ``` pop(&mut self) -> Option<char>253 pub fn pop(&mut self) -> Option<char> { 254 let ch = match self.chars().rev().next() { 255 Some(ch) => ch, 256 None => return None, 257 }; 258 let new_len = self.len() - ch.len_utf8(); 259 unsafe { 260 self.set_len(new_len); 261 } 262 Some(ch) 263 } 264 265 /// Shortens this `ArrayString` to the specified length. 266 /// 267 /// If `new_len` is greater than the string’s current length, this has no 268 /// effect. 269 /// 270 /// ***Panics*** if `new_len` does not lie on a `char` boundary. 271 /// 272 /// ``` 273 /// use arrayvec::ArrayString; 274 /// 275 /// let mut string = ArrayString::<[_; 6]>::from("foobar").unwrap(); 276 /// string.truncate(3); 277 /// assert_eq!(&string[..], "foo"); 278 /// string.truncate(4); 279 /// assert_eq!(&string[..], "foo"); 280 /// ``` truncate(&mut self, new_len: usize)281 pub fn truncate(&mut self, new_len: usize) { 282 if new_len <= self.len() { 283 assert!(self.is_char_boundary(new_len)); 284 unsafe { 285 // In libstd truncate is called on the underlying vector, 286 // which in turns drops each element. 287 // As we know we don't have to worry about Drop, 288 // we can just set the length (a la clear.) 289 self.set_len(new_len); 290 } 291 } 292 } 293 294 /// Removes a `char` from this `ArrayString` at a byte position and returns it. 295 /// 296 /// This is an `O(n)` operation, as it requires copying every element in the 297 /// array. 298 /// 299 /// ***Panics*** if `idx` is larger than or equal to the `ArrayString`’s length, 300 /// or if it does not lie on a `char` boundary. 301 /// 302 /// ``` 303 /// use arrayvec::ArrayString; 304 /// 305 /// let mut s = ArrayString::<[_; 3]>::from("foo").unwrap(); 306 /// 307 /// assert_eq!(s.remove(0), 'f'); 308 /// assert_eq!(s.remove(1), 'o'); 309 /// assert_eq!(s.remove(0), 'o'); 310 /// ``` remove(&mut self, idx: usize) -> char311 pub fn remove(&mut self, idx: usize) -> char { 312 let ch = match self[idx..].chars().next() { 313 Some(ch) => ch, 314 None => panic!("cannot remove a char from the end of a string"), 315 }; 316 317 let next = idx + ch.len_utf8(); 318 let len = self.len(); 319 unsafe { 320 ptr::copy(self.xs.ptr().offset(next as isize), 321 self.xs.ptr_mut().offset(idx as isize), 322 len - next); 323 self.set_len(len - (next - idx)); 324 } 325 ch 326 } 327 328 /// Make the string empty. clear(&mut self)329 pub fn clear(&mut self) { 330 unsafe { 331 self.set_len(0); 332 } 333 } 334 335 /// Set the strings’s length. 336 /// 337 /// This function is `unsafe` because it changes the notion of the 338 /// number of “valid” bytes in the string. Use with care. 339 /// 340 /// This method uses *debug assertions* to check the validity of `length` 341 /// and may use other debug assertions. set_len(&mut self, length: usize)342 pub unsafe fn set_len(&mut self, length: usize) { 343 debug_assert!(length <= self.capacity()); 344 self.len = Index::from(length); 345 } 346 347 /// Return a string slice of the whole `ArrayString`. as_str(&self) -> &str348 pub fn as_str(&self) -> &str { 349 self 350 } 351 } 352 353 impl<A> Deref for ArrayString<A> 354 where A: Array<Item=u8> + Copy 355 { 356 type Target = str; 357 #[inline] deref(&self) -> &str358 fn deref(&self) -> &str { 359 unsafe { 360 let sl = slice::from_raw_parts(self.xs.ptr(), self.len.to_usize()); 361 str::from_utf8_unchecked(sl) 362 } 363 } 364 } 365 366 impl<A> DerefMut for ArrayString<A> 367 where A: Array<Item=u8> + Copy 368 { 369 #[inline] deref_mut(&mut self) -> &mut str370 fn deref_mut(&mut self) -> &mut str { 371 unsafe { 372 let sl = slice::from_raw_parts_mut(self.xs.ptr_mut(), self.len.to_usize()); 373 str::from_utf8_unchecked_mut(sl) 374 } 375 } 376 } 377 378 impl<A> PartialEq for ArrayString<A> 379 where A: Array<Item=u8> + Copy 380 { eq(&self, rhs: &Self) -> bool381 fn eq(&self, rhs: &Self) -> bool { 382 **self == **rhs 383 } 384 } 385 386 impl<A> PartialEq<str> for ArrayString<A> 387 where A: Array<Item=u8> + Copy 388 { eq(&self, rhs: &str) -> bool389 fn eq(&self, rhs: &str) -> bool { 390 &**self == rhs 391 } 392 } 393 394 impl<A> PartialEq<ArrayString<A>> for str 395 where A: Array<Item=u8> + Copy 396 { eq(&self, rhs: &ArrayString<A>) -> bool397 fn eq(&self, rhs: &ArrayString<A>) -> bool { 398 self == &**rhs 399 } 400 } 401 402 impl<A> Eq for ArrayString<A> 403 where A: Array<Item=u8> + Copy 404 { } 405 406 impl<A> Hash for ArrayString<A> 407 where A: Array<Item=u8> + Copy 408 { hash<H: Hasher>(&self, h: &mut H)409 fn hash<H: Hasher>(&self, h: &mut H) { 410 (**self).hash(h) 411 } 412 } 413 414 impl<A> Borrow<str> for ArrayString<A> 415 where A: Array<Item=u8> + Copy 416 { borrow(&self) -> &str417 fn borrow(&self) -> &str { self } 418 } 419 420 impl<A> AsRef<str> for ArrayString<A> 421 where A: Array<Item=u8> + Copy 422 { as_ref(&self) -> &str423 fn as_ref(&self) -> &str { self } 424 } 425 426 impl<A> fmt::Debug for ArrayString<A> 427 where A: Array<Item=u8> + Copy 428 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result429 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } 430 } 431 432 impl<A> fmt::Display for ArrayString<A> 433 where A: Array<Item=u8> + Copy 434 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result435 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } 436 } 437 438 /// `Write` appends written data to the end of the string. 439 impl<A> fmt::Write for ArrayString<A> 440 where A: Array<Item=u8> + Copy 441 { write_char(&mut self, c: char) -> fmt::Result442 fn write_char(&mut self, c: char) -> fmt::Result { 443 self.try_push(c).map_err(|_| fmt::Error) 444 } 445 write_str(&mut self, s: &str) -> fmt::Result446 fn write_str(&mut self, s: &str) -> fmt::Result { 447 self.try_push_str(s).map_err(|_| fmt::Error) 448 } 449 } 450 451 impl<A> Clone for ArrayString<A> 452 where A: Array<Item=u8> + Copy 453 { clone(&self) -> ArrayString<A>454 fn clone(&self) -> ArrayString<A> { 455 *self 456 } clone_from(&mut self, rhs: &Self)457 fn clone_from(&mut self, rhs: &Self) { 458 // guaranteed to fit due to types matching. 459 self.clear(); 460 self.try_push_str(rhs).ok(); 461 } 462 } 463 464 impl<A> PartialOrd for ArrayString<A> 465 where A: Array<Item=u8> + Copy 466 { partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering>467 fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> { 468 (**self).partial_cmp(&**rhs) 469 } lt(&self, rhs: &Self) -> bool470 fn lt(&self, rhs: &Self) -> bool { **self < **rhs } le(&self, rhs: &Self) -> bool471 fn le(&self, rhs: &Self) -> bool { **self <= **rhs } gt(&self, rhs: &Self) -> bool472 fn gt(&self, rhs: &Self) -> bool { **self > **rhs } ge(&self, rhs: &Self) -> bool473 fn ge(&self, rhs: &Self) -> bool { **self >= **rhs } 474 } 475 476 impl<A> PartialOrd<str> for ArrayString<A> 477 where A: Array<Item=u8> + Copy 478 { partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering>479 fn partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering> { 480 (**self).partial_cmp(rhs) 481 } lt(&self, rhs: &str) -> bool482 fn lt(&self, rhs: &str) -> bool { &**self < rhs } le(&self, rhs: &str) -> bool483 fn le(&self, rhs: &str) -> bool { &**self <= rhs } gt(&self, rhs: &str) -> bool484 fn gt(&self, rhs: &str) -> bool { &**self > rhs } ge(&self, rhs: &str) -> bool485 fn ge(&self, rhs: &str) -> bool { &**self >= rhs } 486 } 487 488 impl<A> PartialOrd<ArrayString<A>> for str 489 where A: Array<Item=u8> + Copy 490 { partial_cmp(&self, rhs: &ArrayString<A>) -> Option<cmp::Ordering>491 fn partial_cmp(&self, rhs: &ArrayString<A>) -> Option<cmp::Ordering> { 492 self.partial_cmp(&**rhs) 493 } lt(&self, rhs: &ArrayString<A>) -> bool494 fn lt(&self, rhs: &ArrayString<A>) -> bool { self < &**rhs } le(&self, rhs: &ArrayString<A>) -> bool495 fn le(&self, rhs: &ArrayString<A>) -> bool { self <= &**rhs } gt(&self, rhs: &ArrayString<A>) -> bool496 fn gt(&self, rhs: &ArrayString<A>) -> bool { self > &**rhs } ge(&self, rhs: &ArrayString<A>) -> bool497 fn ge(&self, rhs: &ArrayString<A>) -> bool { self >= &**rhs } 498 } 499 500 impl<A> Ord for ArrayString<A> 501 where A: Array<Item=u8> + Copy 502 { cmp(&self, rhs: &Self) -> cmp::Ordering503 fn cmp(&self, rhs: &Self) -> cmp::Ordering { 504 (**self).cmp(&**rhs) 505 } 506 } 507 508 impl<A> FromStr for ArrayString<A> 509 where A: Array<Item=u8> + Copy 510 { 511 type Err = CapacityError; 512 from_str(s: &str) -> Result<Self, Self::Err>513 fn from_str(s: &str) -> Result<Self, Self::Err> { 514 Self::from(s).map_err(CapacityError::simplify) 515 } 516 } 517 518 #[cfg(feature="serde")] 519 /// Requires crate feature `"serde"` 520 impl<A> Serialize for ArrayString<A> 521 where A: Array<Item=u8> + Copy 522 { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer523 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 524 where S: Serializer 525 { 526 serializer.serialize_str(&*self) 527 } 528 } 529 530 #[cfg(feature="serde")] 531 /// Requires crate feature `"serde"` 532 impl<'de, A> Deserialize<'de> for ArrayString<A> 533 where A: Array<Item=u8> + Copy 534 { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>535 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 536 where D: Deserializer<'de> 537 { 538 use serde::de::{self, Visitor}; 539 use std::marker::PhantomData; 540 541 struct ArrayStringVisitor<A: Array<Item=u8>>(PhantomData<A>); 542 543 impl<'de, A: Copy + Array<Item=u8>> Visitor<'de> for ArrayStringVisitor<A> { 544 type Value = ArrayString<A>; 545 546 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 547 write!(formatter, "a string no more than {} bytes long", A::CAPACITY) 548 } 549 550 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> 551 where E: de::Error, 552 { 553 ArrayString::from(v).map_err(|_| E::invalid_length(v.len(), &self)) 554 } 555 556 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> 557 where E: de::Error, 558 { 559 let s = str::from_utf8(v).map_err(|_| E::invalid_value(de::Unexpected::Bytes(v), &self))?; 560 561 ArrayString::from(s).map_err(|_| E::invalid_length(s.len(), &self)) 562 } 563 } 564 565 deserializer.deserialize_str(ArrayStringVisitor::<A>(PhantomData)) 566 } 567 } 568