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