Coverage Report

Created: 2025-10-10 07:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/arrayvec-0.7.6/src/array_string.rs
Line
Count
Source
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`
46
0
    fn default() -> ArrayString<CAP> {
47
0
        ArrayString::new()
48
0
    }
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
    /// ```
65
0
    pub fn new() -> ArrayString<CAP> {
66
0
        assert_capacity_limit!(CAP);
67
        unsafe {
68
0
            ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 }
69
        }
70
0
    }
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
    /// ```
81
0
    pub const fn new_const() -> ArrayString<CAP> {
82
0
        assert_capacity_limit_const!(CAP);
83
0
        ArrayString { xs: MakeMaybeUninit::ARRAY, len: 0 }
84
0
    }
85
86
    /// Return the length of the string.
87
    #[inline]
88
0
    pub const fn len(&self) -> usize { self.len as usize }
89
90
    /// Returns whether the string is empty.
91
    #[inline]
92
0
    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
    /// ```
108
0
    pub fn from(s: &str) -> Result<Self, CapacityError<&str>> {
109
0
        let mut arraystr = Self::new();
110
0
        arraystr.try_push_str(s)?;
111
0
        Ok(arraystr)
112
0
    }
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
    /// ```
123
0
    pub fn from_byte_string(b: &[u8; CAP]) -> Result<Self, Utf8Error> {
124
0
        let len = str::from_utf8(b)?.len();
125
0
        debug_assert_eq!(len, CAP);
126
0
        let mut vec = Self::new();
127
0
        unsafe {
128
0
            (b as *const [u8; CAP] as *const [MaybeUninit<u8>; CAP])
129
0
                .copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit<u8>; CAP], 1);
130
0
            vec.set_len(CAP);
131
0
        }
132
0
        Ok(vec)
133
0
    }
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]
145
0
    pub fn zero_filled() -> Self {
146
0
        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
0
            ArrayString {
151
0
                xs: MaybeUninit::zeroed().assume_init(),
152
0
                len: CAP as _
153
0
            }
154
        }
155
0
    }
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)]
166
0
    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
    /// ```
178
0
    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
    /// ```
189
0
    pub const fn remaining_capacity(&self) -> usize {
190
0
        self.capacity() - self.len()
191
0
    }
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]
208
0
    pub fn push(&mut self, c: char) {
209
0
        self.try_push(c).unwrap();
210
0
    }
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
    /// ```
230
0
    pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> {
231
0
        let len = self.len();
232
        unsafe {
233
0
            let ptr = self.as_mut_ptr().add(len);
234
0
            let remaining_cap = self.capacity() - len;
235
0
            match encode_utf8(c, ptr, remaining_cap) {
236
0
                Ok(n) => {
237
0
                    self.set_len(len + n);
238
0
                    Ok(())
239
                }
240
0
                Err(_) => Err(CapacityError::new(c)),
241
            }
242
        }
243
0
    }
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]
260
0
    pub fn push_str(&mut self, s: &str) {
261
0
        self.try_push_str(s).unwrap()
262
0
    }
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
    /// ```
284
0
    pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
285
0
        if s.len() > self.capacity() - self.len() {
286
0
            return Err(CapacityError::new(s));
287
0
        }
288
0
        unsafe {
289
0
            let dst = self.as_mut_ptr().add(self.len());
290
0
            let src = s.as_ptr();
291
0
            ptr::copy_nonoverlapping(src, dst, s.len());
292
0
            let newl = self.len() + s.len();
293
0
            self.set_len(newl);
294
0
        }
295
0
        Ok(())
296
0
    }
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
    /// ```
313
0
    pub fn pop(&mut self) -> Option<char> {
314
0
        let ch = match self.chars().rev().next() {
315
0
            Some(ch) => ch,
316
0
            None => return None,
317
        };
318
0
        let new_len = self.len() - ch.len_utf8();
319
0
        unsafe {
320
0
            self.set_len(new_len);
321
0
        }
322
0
        Some(ch)
323
0
    }
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
    /// ```
341
0
    pub fn truncate(&mut self, new_len: usize) {
342
0
        if new_len <= self.len() {
343
0
            assert!(self.is_char_boundary(new_len));
344
0
            unsafe { 
345
0
                // In libstd truncate is called on the underlying vector,
346
0
                // which in turns drops each element.
347
0
                // As we know we don't have to worry about Drop,
348
0
                // we can just set the length (a la clear.)
349
0
                self.set_len(new_len);
350
0
            }
351
0
        }
352
0
    }
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
    /// ```
371
0
    pub fn remove(&mut self, idx: usize) -> char {
372
0
        let ch = match self[idx..].chars().next() {
373
0
            Some(ch) => ch,
374
0
            None => panic!("cannot remove a char from the end of a string"),
375
        };
376
377
0
        let next = idx + ch.len_utf8();
378
0
        let len = self.len();
379
0
        let ptr = self.as_mut_ptr();
380
0
        unsafe {
381
0
            ptr::copy(
382
0
                ptr.add(next),
383
0
                ptr.add(idx),
384
0
                len - next);
385
0
            self.set_len(len - (next - idx));
386
0
        }
387
0
        ch
388
0
    }
389
390
    /// Make the string empty.
391
0
    pub fn clear(&mut self) {
392
0
        unsafe {
393
0
            self.set_len(0);
394
0
        }
395
0
    }
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.
404
0
    pub unsafe fn set_len(&mut self, length: usize) {
405
        // type invariant that capacity always fits in LenUint
406
0
        debug_assert!(length <= self.capacity());
407
0
        self.len = length as LenUint;
408
0
    }
409
410
    /// Return a string slice of the whole `ArrayString`.
411
0
    pub fn as_str(&self) -> &str {
412
0
        self
413
0
    }
414
415
    /// Return a mutable string slice of the whole `ArrayString`.
416
0
    pub fn as_mut_str(&mut self) -> &mut str {
417
0
        self
418
0
    }
419
420
    /// Return a raw pointer to the string's buffer.
421
0
    pub fn as_ptr(&self) -> *const u8 {
422
0
        self.xs.as_ptr() as *const u8
423
0
    }
424
425
    /// Return a raw mutable pointer to the string's buffer.
426
0
    pub fn as_mut_ptr(&mut self) -> *mut u8 {
427
0
        self.xs.as_mut_ptr() as *mut u8
428
0
    }
429
}
430
431
impl<const CAP: usize> Deref for ArrayString<CAP>
432
{
433
    type Target = str;
434
    #[inline]
435
0
    fn deref(&self) -> &str {
436
        unsafe {
437
0
            let sl = slice::from_raw_parts(self.as_ptr(), self.len());
438
0
            str::from_utf8_unchecked(sl)
439
        }
440
0
    }
441
}
442
443
impl<const CAP: usize> DerefMut for ArrayString<CAP>
444
{
445
    #[inline]
446
0
    fn deref_mut(&mut self) -> &mut str {
447
0
        unsafe {
448
0
            let len = self.len();
449
0
            let sl = slice::from_raw_parts_mut(self.as_mut_ptr(), len);
450
0
            str::from_utf8_unchecked_mut(sl)
451
0
        }
452
0
    }
453
}
454
455
impl<const CAP: usize> PartialEq for ArrayString<CAP>
456
{
457
0
    fn eq(&self, rhs: &Self) -> bool {
458
0
        **self == **rhs
459
0
    }
460
}
461
462
impl<const CAP: usize> PartialEq<str> for ArrayString<CAP>
463
{
464
0
    fn eq(&self, rhs: &str) -> bool {
465
0
        &**self == rhs
466
0
    }
467
}
468
469
impl<const CAP: usize> PartialEq<ArrayString<CAP>> for str
470
{
471
0
    fn eq(&self, rhs: &ArrayString<CAP>) -> bool {
472
0
        self == &**rhs
473
0
    }
474
}
475
476
impl<const CAP: usize> Eq for ArrayString<CAP> 
477
{ }
478
479
impl<const CAP: usize> Hash for ArrayString<CAP>
480
{
481
0
    fn hash<H: Hasher>(&self, h: &mut H) {
482
0
        (**self).hash(h)
483
0
    }
484
}
485
486
impl<const CAP: usize> Borrow<str> for ArrayString<CAP>
487
{
488
0
    fn borrow(&self) -> &str { self }
489
}
490
491
impl<const CAP: usize> BorrowMut<str> for ArrayString<CAP>
492
{
493
0
    fn borrow_mut(&mut self) -> &mut str { self }
494
}
495
496
impl<const CAP: usize> AsRef<str> for ArrayString<CAP>
497
{
498
0
    fn as_ref(&self) -> &str { self }
499
}
500
501
impl<const CAP: usize> fmt::Debug for ArrayString<CAP>
502
{
503
0
    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> {
508
0
    fn as_ref(&self) -> &Path {
509
0
        self.as_str().as_ref()
510
0
    }
511
}
512
513
impl<const CAP: usize> fmt::Display for ArrayString<CAP>
514
{
515
0
    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
{
521
0
    fn write_char(&mut self, c: char) -> fmt::Result {
522
0
        self.try_push(c).map_err(|_| fmt::Error)
523
0
    }
524
525
0
    fn write_str(&mut self, s: &str) -> fmt::Result {
526
0
        self.try_push_str(s).map_err(|_| fmt::Error)
527
0
    }
528
}
529
530
impl<const CAP: usize> Clone for ArrayString<CAP>
531
{
532
0
    fn clone(&self) -> ArrayString<CAP> {
533
0
        *self
534
0
    }
535
0
    fn clone_from(&mut self, rhs: &Self) {
536
        // guaranteed to fit due to types matching.
537
0
        self.clear();
538
0
        self.try_push_str(rhs).ok();
539
0
    }
540
}
541
542
impl<const CAP: usize> PartialOrd for ArrayString<CAP>
543
{
544
0
    fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> {
545
0
        (**self).partial_cmp(&**rhs)
546
0
    }
547
0
    fn lt(&self, rhs: &Self) -> bool { **self < **rhs }
548
0
    fn le(&self, rhs: &Self) -> bool { **self <= **rhs }
549
0
    fn gt(&self, rhs: &Self) -> bool { **self > **rhs }
550
0
    fn ge(&self, rhs: &Self) -> bool { **self >= **rhs }
551
}
552
553
impl<const CAP: usize> PartialOrd<str> for ArrayString<CAP>
554
{
555
0
    fn partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering> {
556
0
        (**self).partial_cmp(rhs)
557
0
    }
558
0
    fn lt(&self, rhs: &str) -> bool { &**self < rhs }
559
0
    fn le(&self, rhs: &str) -> bool { &**self <= rhs }
560
0
    fn gt(&self, rhs: &str) -> bool { &**self > rhs }
561
0
    fn ge(&self, rhs: &str) -> bool { &**self >= rhs }
562
}
563
564
impl<const CAP: usize> PartialOrd<ArrayString<CAP>> for str
565
{
566
0
    fn partial_cmp(&self, rhs: &ArrayString<CAP>) -> Option<cmp::Ordering> {
567
0
        self.partial_cmp(&**rhs)
568
0
    }
569
0
    fn lt(&self, rhs: &ArrayString<CAP>) -> bool { self < &**rhs }
570
0
    fn le(&self, rhs: &ArrayString<CAP>) -> bool { self <= &**rhs }
571
0
    fn gt(&self, rhs: &ArrayString<CAP>) -> bool { self > &**rhs }
572
0
    fn ge(&self, rhs: &ArrayString<CAP>) -> bool { self >= &**rhs }
573
}
574
575
impl<const CAP: usize> Ord for ArrayString<CAP>
576
{
577
0
    fn cmp(&self, rhs: &Self) -> cmp::Ordering {
578
0
        (**self).cmp(&**rhs)
579
0
    }
580
}
581
582
impl<const CAP: usize> FromStr for ArrayString<CAP>
583
{
584
    type Err = CapacityError;
585
586
0
    fn from_str(s: &str) -> Result<Self, Self::Err> {
587
0
        Self::from(s).map_err(CapacityError::simplify)
588
0
    }
589
}
590
591
#[cfg(feature="serde")]
592
/// Requires crate feature `"serde"`
593
impl<const CAP: usize> Serialize for ArrayString<CAP>
594
{
595
    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
{
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> {
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> {
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
675
0
    fn try_from(f: &'a str) -> Result<Self, Self::Error> {
676
0
        let mut v = Self::new();
677
0
        v.try_push_str(f)?;
678
0
        Ok(v)
679
0
    }
680
}
681
682
impl<'a, const CAP: usize> TryFrom<fmt::Arguments<'a>> for ArrayString<CAP>
683
{
684
    type Error = CapacityError<fmt::Error>;
685
686
0
    fn try_from(f: fmt::Arguments<'a>) -> Result<Self, Self::Error> {
687
        use fmt::Write;
688
0
        let mut v = Self::new();
689
0
        v.write_fmt(f).map_err(|e| CapacityError::new(e))?;
690
0
        Ok(v)
691
0
    }
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> {
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
}