• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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