1 use std::borrow::{Borrow, BorrowMut}; 2 use std::cmp; 3 use std::convert::TryFrom; 4 use std::fmt; 5 use std::hash::{Hash, Hasher}; 6 use std::mem::MaybeUninit; 7 use std::ops::{Deref, DerefMut}; 8 #[cfg(feature="std")] 9 use std::path::Path; 10 use std::ptr; 11 use std::slice; 12 use std::str; 13 use std::str::FromStr; 14 use std::str::Utf8Error; 15 16 use crate::CapacityError; 17 use crate::LenUint; 18 use crate::char::encode_utf8; 19 use crate::utils::MakeMaybeUninit; 20 21 #[cfg(feature="serde")] 22 use serde::{Serialize, Deserialize, Serializer, Deserializer}; 23 24 25 /// A string with a fixed capacity. 26 /// 27 /// The `ArrayString` is a string backed by a fixed size array. It keeps track 28 /// of its length, and is parameterized by `CAP` for the maximum capacity. 29 /// 30 /// `CAP` is of type `usize` but is range limited to `u32::MAX`; attempting to create larger 31 /// arrayvecs with larger capacity will panic. 32 /// 33 /// The string is a contiguous value that you can store directly on the stack 34 /// if needed. 35 #[derive(Copy)] 36 #[repr(C)] 37 pub struct ArrayString<const CAP: usize> { 38 // the `len` first elements of the array are initialized 39 len: LenUint, 40 xs: [MaybeUninit<u8>; CAP], 41 } 42 43 impl<const CAP: usize> Default for ArrayString<CAP> 44 { 45 /// Return an empty `ArrayString` default() -> ArrayString<CAP>46 fn default() -> ArrayString<CAP> { 47 ArrayString::new() 48 } 49 } 50 51 impl<const CAP: usize> ArrayString<CAP> 52 { 53 /// Create a new empty `ArrayString`. 54 /// 55 /// Capacity is inferred from the type parameter. 56 /// 57 /// ``` 58 /// use arrayvec::ArrayString; 59 /// 60 /// let mut string = ArrayString::<16>::new(); 61 /// string.push_str("foo"); 62 /// assert_eq!(&string[..], "foo"); 63 /// assert_eq!(string.capacity(), 16); 64 /// ``` new() -> ArrayString<CAP>65 pub fn new() -> ArrayString<CAP> { 66 assert_capacity_limit!(CAP); 67 unsafe { 68 ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 } 69 } 70 } 71 72 /// Create a new empty `ArrayString` (const fn). 73 /// 74 /// Capacity is inferred from the type parameter. 75 /// 76 /// ``` 77 /// use arrayvec::ArrayString; 78 /// 79 /// static ARRAY: ArrayString<1024> = ArrayString::new_const(); 80 /// ``` new_const() -> ArrayString<CAP>81 pub const fn new_const() -> ArrayString<CAP> { 82 assert_capacity_limit_const!(CAP); 83 ArrayString { xs: MakeMaybeUninit::ARRAY, len: 0 } 84 } 85 86 /// Return the length of the string. 87 #[inline] len(&self) -> usize88 pub const fn len(&self) -> usize { self.len as usize } 89 90 /// Returns whether the string is empty. 91 #[inline] is_empty(&self) -> bool92 pub const fn is_empty(&self) -> bool { self.len() == 0 } 93 94 /// Create a new `ArrayString` from a `str`. 95 /// 96 /// Capacity is inferred from the type parameter. 97 /// 98 /// **Errors** if the backing array is not large enough to fit the string. 99 /// 100 /// ``` 101 /// use arrayvec::ArrayString; 102 /// 103 /// let mut string = ArrayString::<3>::from("foo").unwrap(); 104 /// assert_eq!(&string[..], "foo"); 105 /// assert_eq!(string.len(), 3); 106 /// assert_eq!(string.capacity(), 3); 107 /// ``` from(s: &str) -> Result<Self, CapacityError<&str>>108 pub fn from(s: &str) -> Result<Self, CapacityError<&str>> { 109 let mut arraystr = Self::new(); 110 arraystr.try_push_str(s)?; 111 Ok(arraystr) 112 } 113 114 /// Create a new `ArrayString` from a byte string literal. 115 /// 116 /// **Errors** if the byte string literal is not valid UTF-8. 117 /// 118 /// ``` 119 /// use arrayvec::ArrayString; 120 /// 121 /// let string = ArrayString::from_byte_string(b"hello world").unwrap(); 122 /// ``` from_byte_string(b: &[u8; CAP]) -> Result<Self, Utf8Error>123 pub fn from_byte_string(b: &[u8; CAP]) -> Result<Self, Utf8Error> { 124 let len = str::from_utf8(b)?.len(); 125 debug_assert_eq!(len, CAP); 126 let mut vec = Self::new(); 127 unsafe { 128 (b as *const [u8; CAP] as *const [MaybeUninit<u8>; CAP]) 129 .copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit<u8>; CAP], 1); 130 vec.set_len(CAP); 131 } 132 Ok(vec) 133 } 134 135 /// Create a new `ArrayString` value fully filled with ASCII NULL characters (`\0`). Useful 136 /// to be used as a buffer to collect external data or as a buffer for intermediate processing. 137 /// 138 /// ``` 139 /// use arrayvec::ArrayString; 140 /// 141 /// let string = ArrayString::<16>::zero_filled(); 142 /// assert_eq!(string.len(), 16); 143 /// ``` 144 #[inline] zero_filled() -> Self145 pub fn zero_filled() -> Self { 146 assert_capacity_limit!(CAP); 147 // SAFETY: `assert_capacity_limit` asserts that `len` won't overflow and 148 // `zeroed` fully fills the array with nulls. 149 unsafe { 150 ArrayString { 151 xs: MaybeUninit::zeroed().assume_init(), 152 len: CAP as _ 153 } 154 } 155 } 156 157 /// Return the capacity of the `ArrayString`. 158 /// 159 /// ``` 160 /// use arrayvec::ArrayString; 161 /// 162 /// let string = ArrayString::<3>::new(); 163 /// assert_eq!(string.capacity(), 3); 164 /// ``` 165 #[inline(always)] capacity(&self) -> usize166 pub const fn capacity(&self) -> usize { CAP } 167 168 /// Return if the `ArrayString` is completely filled. 169 /// 170 /// ``` 171 /// use arrayvec::ArrayString; 172 /// 173 /// let mut string = ArrayString::<1>::new(); 174 /// assert!(!string.is_full()); 175 /// string.push_str("A"); 176 /// assert!(string.is_full()); 177 /// ``` is_full(&self) -> bool178 pub const fn is_full(&self) -> bool { self.len() == self.capacity() } 179 180 /// Returns the capacity left in the `ArrayString`. 181 /// 182 /// ``` 183 /// use arrayvec::ArrayString; 184 /// 185 /// let mut string = ArrayString::<3>::from("abc").unwrap(); 186 /// string.pop(); 187 /// assert_eq!(string.remaining_capacity(), 1); 188 /// ``` remaining_capacity(&self) -> usize189 pub const fn remaining_capacity(&self) -> usize { 190 self.capacity() - self.len() 191 } 192 193 /// Adds the given char to the end of the string. 194 /// 195 /// ***Panics*** if the backing array is not large enough to fit the additional char. 196 /// 197 /// ``` 198 /// use arrayvec::ArrayString; 199 /// 200 /// let mut string = ArrayString::<2>::new(); 201 /// 202 /// string.push('a'); 203 /// string.push('b'); 204 /// 205 /// assert_eq!(&string[..], "ab"); 206 /// ``` 207 #[track_caller] push(&mut self, c: char)208 pub fn push(&mut self, c: char) { 209 self.try_push(c).unwrap(); 210 } 211 212 /// Adds the given char to the end of the string. 213 /// 214 /// Returns `Ok` if the push succeeds. 215 /// 216 /// **Errors** if the backing array is not large enough to fit the additional char. 217 /// 218 /// ``` 219 /// use arrayvec::ArrayString; 220 /// 221 /// let mut string = ArrayString::<2>::new(); 222 /// 223 /// string.try_push('a').unwrap(); 224 /// string.try_push('b').unwrap(); 225 /// let overflow = string.try_push('c'); 226 /// 227 /// assert_eq!(&string[..], "ab"); 228 /// assert_eq!(overflow.unwrap_err().element(), 'c'); 229 /// ``` try_push(&mut self, c: char) -> Result<(), CapacityError<char>>230 pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> { 231 let len = self.len(); 232 unsafe { 233 let ptr = self.as_mut_ptr().add(len); 234 let remaining_cap = self.capacity() - len; 235 match encode_utf8(c, ptr, remaining_cap) { 236 Ok(n) => { 237 self.set_len(len + n); 238 Ok(()) 239 } 240 Err(_) => Err(CapacityError::new(c)), 241 } 242 } 243 } 244 245 /// Adds the given string slice to the end of the string. 246 /// 247 /// ***Panics*** if the backing array is not large enough to fit the string. 248 /// 249 /// ``` 250 /// use arrayvec::ArrayString; 251 /// 252 /// let mut string = ArrayString::<2>::new(); 253 /// 254 /// string.push_str("a"); 255 /// string.push_str("d"); 256 /// 257 /// assert_eq!(&string[..], "ad"); 258 /// ``` 259 #[track_caller] push_str(&mut self, s: &str)260 pub fn push_str(&mut self, s: &str) { 261 self.try_push_str(s).unwrap() 262 } 263 264 /// Adds the given string slice to the end of the string. 265 /// 266 /// Returns `Ok` if the push succeeds. 267 /// 268 /// **Errors** if the backing array is not large enough to fit the string. 269 /// 270 /// ``` 271 /// use arrayvec::ArrayString; 272 /// 273 /// let mut string = ArrayString::<2>::new(); 274 /// 275 /// string.try_push_str("a").unwrap(); 276 /// let overflow1 = string.try_push_str("bc"); 277 /// string.try_push_str("d").unwrap(); 278 /// let overflow2 = string.try_push_str("ef"); 279 /// 280 /// assert_eq!(&string[..], "ad"); 281 /// assert_eq!(overflow1.unwrap_err().element(), "bc"); 282 /// assert_eq!(overflow2.unwrap_err().element(), "ef"); 283 /// ``` try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>>284 pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> { 285 if s.len() > self.capacity() - self.len() { 286 return Err(CapacityError::new(s)); 287 } 288 unsafe { 289 let dst = self.as_mut_ptr().add(self.len()); 290 let src = s.as_ptr(); 291 ptr::copy_nonoverlapping(src, dst, s.len()); 292 let newl = self.len() + s.len(); 293 self.set_len(newl); 294 } 295 Ok(()) 296 } 297 298 /// Removes the last character from the string and returns it. 299 /// 300 /// Returns `None` if this `ArrayString` is empty. 301 /// 302 /// ``` 303 /// use arrayvec::ArrayString; 304 /// 305 /// let mut s = ArrayString::<3>::from("foo").unwrap(); 306 /// 307 /// assert_eq!(s.pop(), Some('o')); 308 /// assert_eq!(s.pop(), Some('o')); 309 /// assert_eq!(s.pop(), Some('f')); 310 /// 311 /// assert_eq!(s.pop(), None); 312 /// ``` pop(&mut self) -> Option<char>313 pub fn pop(&mut self) -> Option<char> { 314 let ch = match self.chars().rev().next() { 315 Some(ch) => ch, 316 None => return None, 317 }; 318 let new_len = self.len() - ch.len_utf8(); 319 unsafe { 320 self.set_len(new_len); 321 } 322 Some(ch) 323 } 324 325 /// Shortens this `ArrayString` to the specified length. 326 /// 327 /// If `new_len` is greater than the string’s current length, this has no 328 /// effect. 329 /// 330 /// ***Panics*** if `new_len` does not lie on a `char` boundary. 331 /// 332 /// ``` 333 /// use arrayvec::ArrayString; 334 /// 335 /// let mut string = ArrayString::<6>::from("foobar").unwrap(); 336 /// string.truncate(3); 337 /// assert_eq!(&string[..], "foo"); 338 /// string.truncate(4); 339 /// assert_eq!(&string[..], "foo"); 340 /// ``` truncate(&mut self, new_len: usize)341 pub fn truncate(&mut self, new_len: usize) { 342 if new_len <= self.len() { 343 assert!(self.is_char_boundary(new_len)); 344 unsafe { 345 // In libstd truncate is called on the underlying vector, 346 // which in turns drops each element. 347 // As we know we don't have to worry about Drop, 348 // we can just set the length (a la clear.) 349 self.set_len(new_len); 350 } 351 } 352 } 353 354 /// Removes a `char` from this `ArrayString` at a byte position and returns it. 355 /// 356 /// This is an `O(n)` operation, as it requires copying every element in the 357 /// array. 358 /// 359 /// ***Panics*** if `idx` is larger than or equal to the `ArrayString`’s length, 360 /// or if it does not lie on a `char` boundary. 361 /// 362 /// ``` 363 /// use arrayvec::ArrayString; 364 /// 365 /// let mut s = ArrayString::<3>::from("foo").unwrap(); 366 /// 367 /// assert_eq!(s.remove(0), 'f'); 368 /// assert_eq!(s.remove(1), 'o'); 369 /// assert_eq!(s.remove(0), 'o'); 370 /// ``` remove(&mut self, idx: usize) -> char371 pub fn remove(&mut self, idx: usize) -> char { 372 let ch = match self[idx..].chars().next() { 373 Some(ch) => ch, 374 None => panic!("cannot remove a char from the end of a string"), 375 }; 376 377 let next = idx + ch.len_utf8(); 378 let len = self.len(); 379 let ptr = self.as_mut_ptr(); 380 unsafe { 381 ptr::copy( 382 ptr.add(next), 383 ptr.add(idx), 384 len - next); 385 self.set_len(len - (next - idx)); 386 } 387 ch 388 } 389 390 /// Make the string empty. clear(&mut self)391 pub fn clear(&mut self) { 392 unsafe { 393 self.set_len(0); 394 } 395 } 396 397 /// Set the strings’s length. 398 /// 399 /// This function is `unsafe` because it changes the notion of the 400 /// number of “valid” bytes in the string. Use with care. 401 /// 402 /// This method uses *debug assertions* to check the validity of `length` 403 /// and may use other debug assertions. set_len(&mut self, length: usize)404 pub unsafe fn set_len(&mut self, length: usize) { 405 // type invariant that capacity always fits in LenUint 406 debug_assert!(length <= self.capacity()); 407 self.len = length as LenUint; 408 } 409 410 /// Return a string slice of the whole `ArrayString`. as_str(&self) -> &str411 pub fn as_str(&self) -> &str { 412 self 413 } 414 415 /// Return a mutable string slice of the whole `ArrayString`. as_mut_str(&mut self) -> &mut str416 pub fn as_mut_str(&mut self) -> &mut str { 417 self 418 } 419 420 /// Return a raw pointer to the string's buffer. as_ptr(&self) -> *const u8421 pub fn as_ptr(&self) -> *const u8 { 422 self.xs.as_ptr() as *const u8 423 } 424 425 /// Return a raw mutable pointer to the string's buffer. as_mut_ptr(&mut self) -> *mut u8426 pub fn as_mut_ptr(&mut self) -> *mut u8 { 427 self.xs.as_mut_ptr() as *mut u8 428 } 429 } 430 431 impl<const CAP: usize> Deref for ArrayString<CAP> 432 { 433 type Target = str; 434 #[inline] deref(&self) -> &str435 fn deref(&self) -> &str { 436 unsafe { 437 let sl = slice::from_raw_parts(self.as_ptr(), self.len()); 438 str::from_utf8_unchecked(sl) 439 } 440 } 441 } 442 443 impl<const CAP: usize> DerefMut for ArrayString<CAP> 444 { 445 #[inline] deref_mut(&mut self) -> &mut str446 fn deref_mut(&mut self) -> &mut str { 447 unsafe { 448 let len = self.len(); 449 let sl = slice::from_raw_parts_mut(self.as_mut_ptr(), len); 450 str::from_utf8_unchecked_mut(sl) 451 } 452 } 453 } 454 455 impl<const CAP: usize> PartialEq for ArrayString<CAP> 456 { eq(&self, rhs: &Self) -> bool457 fn eq(&self, rhs: &Self) -> bool { 458 **self == **rhs 459 } 460 } 461 462 impl<const CAP: usize> PartialEq<str> for ArrayString<CAP> 463 { eq(&self, rhs: &str) -> bool464 fn eq(&self, rhs: &str) -> bool { 465 &**self == rhs 466 } 467 } 468 469 impl<const CAP: usize> PartialEq<ArrayString<CAP>> for str 470 { eq(&self, rhs: &ArrayString<CAP>) -> bool471 fn eq(&self, rhs: &ArrayString<CAP>) -> bool { 472 self == &**rhs 473 } 474 } 475 476 impl<const CAP: usize> Eq for ArrayString<CAP> 477 { } 478 479 impl<const CAP: usize> Hash for ArrayString<CAP> 480 { hash<H: Hasher>(&self, h: &mut H)481 fn hash<H: Hasher>(&self, h: &mut H) { 482 (**self).hash(h) 483 } 484 } 485 486 impl<const CAP: usize> Borrow<str> for ArrayString<CAP> 487 { borrow(&self) -> &str488 fn borrow(&self) -> &str { self } 489 } 490 491 impl<const CAP: usize> BorrowMut<str> for ArrayString<CAP> 492 { borrow_mut(&mut self) -> &mut str493 fn borrow_mut(&mut self) -> &mut str { self } 494 } 495 496 impl<const CAP: usize> AsRef<str> for ArrayString<CAP> 497 { as_ref(&self) -> &str498 fn as_ref(&self) -> &str { self } 499 } 500 501 impl<const CAP: usize> fmt::Debug for ArrayString<CAP> 502 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result503 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } 504 } 505 506 #[cfg(feature="std")] 507 impl<const CAP: usize> AsRef<Path> for ArrayString<CAP> { as_ref(&self) -> &Path508 fn as_ref(&self) -> &Path { 509 self.as_str().as_ref() 510 } 511 } 512 513 impl<const CAP: usize> fmt::Display for ArrayString<CAP> 514 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result515 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) } 516 } 517 518 /// `Write` appends written data to the end of the string. 519 impl<const CAP: usize> fmt::Write for ArrayString<CAP> 520 { write_char(&mut self, c: char) -> fmt::Result521 fn write_char(&mut self, c: char) -> fmt::Result { 522 self.try_push(c).map_err(|_| fmt::Error) 523 } 524 write_str(&mut self, s: &str) -> fmt::Result525 fn write_str(&mut self, s: &str) -> fmt::Result { 526 self.try_push_str(s).map_err(|_| fmt::Error) 527 } 528 } 529 530 impl<const CAP: usize> Clone for ArrayString<CAP> 531 { clone(&self) -> ArrayString<CAP>532 fn clone(&self) -> ArrayString<CAP> { 533 *self 534 } clone_from(&mut self, rhs: &Self)535 fn clone_from(&mut self, rhs: &Self) { 536 // guaranteed to fit due to types matching. 537 self.clear(); 538 self.try_push_str(rhs).ok(); 539 } 540 } 541 542 impl<const CAP: usize> PartialOrd for ArrayString<CAP> 543 { partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering>544 fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> { 545 (**self).partial_cmp(&**rhs) 546 } lt(&self, rhs: &Self) -> bool547 fn lt(&self, rhs: &Self) -> bool { **self < **rhs } le(&self, rhs: &Self) -> bool548 fn le(&self, rhs: &Self) -> bool { **self <= **rhs } gt(&self, rhs: &Self) -> bool549 fn gt(&self, rhs: &Self) -> bool { **self > **rhs } ge(&self, rhs: &Self) -> bool550 fn ge(&self, rhs: &Self) -> bool { **self >= **rhs } 551 } 552 553 impl<const CAP: usize> PartialOrd<str> for ArrayString<CAP> 554 { partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering>555 fn partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering> { 556 (**self).partial_cmp(rhs) 557 } lt(&self, rhs: &str) -> bool558 fn lt(&self, rhs: &str) -> bool { &**self < rhs } le(&self, rhs: &str) -> bool559 fn le(&self, rhs: &str) -> bool { &**self <= rhs } gt(&self, rhs: &str) -> bool560 fn gt(&self, rhs: &str) -> bool { &**self > rhs } ge(&self, rhs: &str) -> bool561 fn ge(&self, rhs: &str) -> bool { &**self >= rhs } 562 } 563 564 impl<const CAP: usize> PartialOrd<ArrayString<CAP>> for str 565 { partial_cmp(&self, rhs: &ArrayString<CAP>) -> Option<cmp::Ordering>566 fn partial_cmp(&self, rhs: &ArrayString<CAP>) -> Option<cmp::Ordering> { 567 self.partial_cmp(&**rhs) 568 } lt(&self, rhs: &ArrayString<CAP>) -> bool569 fn lt(&self, rhs: &ArrayString<CAP>) -> bool { self < &**rhs } le(&self, rhs: &ArrayString<CAP>) -> bool570 fn le(&self, rhs: &ArrayString<CAP>) -> bool { self <= &**rhs } gt(&self, rhs: &ArrayString<CAP>) -> bool571 fn gt(&self, rhs: &ArrayString<CAP>) -> bool { self > &**rhs } ge(&self, rhs: &ArrayString<CAP>) -> bool572 fn ge(&self, rhs: &ArrayString<CAP>) -> bool { self >= &**rhs } 573 } 574 575 impl<const CAP: usize> Ord for ArrayString<CAP> 576 { cmp(&self, rhs: &Self) -> cmp::Ordering577 fn cmp(&self, rhs: &Self) -> cmp::Ordering { 578 (**self).cmp(&**rhs) 579 } 580 } 581 582 impl<const CAP: usize> FromStr for ArrayString<CAP> 583 { 584 type Err = CapacityError; 585 from_str(s: &str) -> Result<Self, Self::Err>586 fn from_str(s: &str) -> Result<Self, Self::Err> { 587 Self::from(s).map_err(CapacityError::simplify) 588 } 589 } 590 591 #[cfg(feature="serde")] 592 /// Requires crate feature `"serde"` 593 impl<const CAP: usize> Serialize for ArrayString<CAP> 594 { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer595 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 596 where S: Serializer 597 { 598 serializer.serialize_str(&*self) 599 } 600 } 601 602 #[cfg(feature="serde")] 603 /// Requires crate feature `"serde"` 604 impl<'de, const CAP: usize> Deserialize<'de> for ArrayString<CAP> 605 { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>606 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 607 where D: Deserializer<'de> 608 { 609 use serde::de::{self, Visitor}; 610 use std::marker::PhantomData; 611 612 struct ArrayStringVisitor<const CAP: usize>(PhantomData<[u8; CAP]>); 613 614 impl<'de, const CAP: usize> Visitor<'de> for ArrayStringVisitor<CAP> { 615 type Value = ArrayString<CAP>; 616 617 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 618 write!(formatter, "a string no more than {} bytes long", CAP) 619 } 620 621 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> 622 where E: de::Error, 623 { 624 ArrayString::from(v).map_err(|_| E::invalid_length(v.len(), &self)) 625 } 626 627 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> 628 where E: de::Error, 629 { 630 let s = str::from_utf8(v).map_err(|_| E::invalid_value(de::Unexpected::Bytes(v), &self))?; 631 632 ArrayString::from(s).map_err(|_| E::invalid_length(s.len(), &self)) 633 } 634 } 635 636 deserializer.deserialize_str(ArrayStringVisitor(PhantomData)) 637 } 638 } 639 640 #[cfg(feature = "borsh")] 641 /// Requires crate feature `"borsh"` 642 impl<const CAP: usize> borsh::BorshSerialize for ArrayString<CAP> { serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()>643 fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()> { 644 <str as borsh::BorshSerialize>::serialize(&*self, writer) 645 } 646 } 647 648 #[cfg(feature = "borsh")] 649 /// Requires crate feature `"borsh"` 650 impl<const CAP: usize> borsh::BorshDeserialize for ArrayString<CAP> { deserialize_reader<R: borsh::io::Read>(reader: &mut R) -> borsh::io::Result<Self>651 fn deserialize_reader<R: borsh::io::Read>(reader: &mut R) -> borsh::io::Result<Self> { 652 let len = <u32 as borsh::BorshDeserialize>::deserialize_reader(reader)? as usize; 653 if len > CAP { 654 return Err(borsh::io::Error::new( 655 borsh::io::ErrorKind::InvalidData, 656 format!("Expected a string no more than {} bytes long", CAP), 657 )) 658 } 659 660 let mut buf = [0u8; CAP]; 661 let buf = &mut buf[..len]; 662 reader.read_exact(buf)?; 663 664 let s = str::from_utf8(&buf).map_err(|err| { 665 borsh::io::Error::new(borsh::io::ErrorKind::InvalidData, err.to_string()) 666 })?; 667 Ok(Self::from(s).unwrap()) 668 } 669 } 670 671 impl<'a, const CAP: usize> TryFrom<&'a str> for ArrayString<CAP> 672 { 673 type Error = CapacityError<&'a str>; 674 try_from(f: &'a str) -> Result<Self, Self::Error>675 fn try_from(f: &'a str) -> Result<Self, Self::Error> { 676 let mut v = Self::new(); 677 v.try_push_str(f)?; 678 Ok(v) 679 } 680 } 681 682 impl<'a, const CAP: usize> TryFrom<fmt::Arguments<'a>> for ArrayString<CAP> 683 { 684 type Error = CapacityError<fmt::Error>; 685 try_from(f: fmt::Arguments<'a>) -> Result<Self, Self::Error>686 fn try_from(f: fmt::Arguments<'a>) -> Result<Self, Self::Error> { 687 use fmt::Write; 688 let mut v = Self::new(); 689 v.write_fmt(f).map_err(|e| CapacityError::new(e))?; 690 Ok(v) 691 } 692 } 693 694 #[cfg(feature = "zeroize")] 695 /// "Best efforts" zeroing of the `ArrayString`'s buffer when the `zeroize` feature is enabled. 696 /// 697 /// The length is set to 0, and the buffer is dropped and zeroized. 698 /// Cannot ensure that previous moves of the `ArrayString` did not leave values on the stack. 699 /// 700 /// ``` 701 /// use arrayvec::ArrayString; 702 /// use zeroize::Zeroize; 703 /// let mut string = ArrayString::<6>::from("foobar").unwrap(); 704 /// string.zeroize(); 705 /// assert_eq!(string.len(), 0); 706 /// unsafe { string.set_len(string.capacity()) }; 707 /// assert_eq!(&*string, "\0\0\0\0\0\0"); 708 /// ``` 709 impl<const CAP: usize> zeroize::Zeroize for ArrayString<CAP> { zeroize(&mut self)710 fn zeroize(&mut self) { 711 // There are no elements to drop 712 self.clear(); 713 // Zeroize the backing array. 714 self.xs.zeroize(); 715 } 716 } 717