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