1 #![cfg_attr(rustfmt, rustfmt_skip)]
2 
3 use std::{fmt, mem};
4 use std::borrow::{Borrow, BorrowMut, Cow};
5 use std::error::Error;
6 use std::ffi::{CStr, CString};
7 use std::any::Any;
8 use std::str::FromStr;
9 use std::ops::{Deref, DerefMut, Add, AddAssign, Index, IndexMut};
10 use std::iter::FromIterator;
11 
12 #[cfg(feature = "quickcheck")]
13 use quickcheck::{Arbitrary, Gen};
14 
15 use ascii_char::AsciiChar;
16 use ascii_str::{AsciiStr, AsAsciiStr, AsAsciiStrError};
17 
18 /// A growable string stored as an ASCII encoded buffer.
19 #[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
20 pub struct AsciiString {
21     vec: Vec<AsciiChar>,
22 }
23 
24 impl AsciiString {
25     /// Creates a new, empty ASCII string buffer without allocating.
26     ///
27     /// # Examples
28     /// ```
29     /// # use ascii::AsciiString;
30     /// let mut s = AsciiString::new();
31     /// ```
32     #[inline]
new() -> Self33     pub fn new() -> Self {
34         AsciiString { vec: Vec::new() }
35     }
36 
37     /// Creates a new ASCII string buffer with the given capacity.
38     /// The string will be able to hold exactly `capacity` bytes without reallocating.
39     /// If `capacity` is 0, the ASCII string will not allocate.
40     ///
41     /// # Examples
42     /// ```
43     /// # use ascii::AsciiString;
44     /// let mut s = AsciiString::with_capacity(10);
45     /// ```
46     #[inline]
with_capacity(capacity: usize) -> Self47     pub fn with_capacity(capacity: usize) -> Self {
48         AsciiString { vec: Vec::with_capacity(capacity) }
49     }
50 
51     /// Creates a new `AsciiString` from a length, capacity and pointer.
52     ///
53     /// # Safety
54     ///
55     /// This is highly unsafe, due to the number of invariants that aren't checked:
56     ///
57     /// * The memory at `ptr` need to have been previously allocated by the same allocator this
58     ///   library uses.
59     /// * `length` needs to be less than or equal to `capacity`.
60     /// * `capacity` needs to be the correct value.
61     ///
62     /// Violating these may cause problems like corrupting the allocator's internal datastructures.
63     ///
64     /// # Examples
65     ///
66     /// Basic usage:
67     ///
68     /// ```
69     /// # use ascii::AsciiString;
70     /// use std::mem;
71     ///
72     /// unsafe {
73     ///    let s = AsciiString::from_ascii("hello").unwrap();
74     ///    let ptr = s.as_ptr();
75     ///    let len = s.len();
76     ///    let capacity = s.capacity();
77     ///
78     ///    mem::forget(s);
79     ///
80     ///    let s = AsciiString::from_raw_parts(ptr as *mut _, len, capacity);
81     ///
82     ///    assert_eq!(AsciiString::from_ascii("hello").unwrap(), s);
83     /// }
84     /// ```
85     #[inline]
from_raw_parts(buf: *mut AsciiChar, length: usize, capacity: usize) -> Self86     pub unsafe fn from_raw_parts(buf: *mut AsciiChar, length: usize, capacity: usize) -> Self {
87         AsciiString { vec: Vec::from_raw_parts(buf, length, capacity) }
88     }
89 
90     /// Converts a vector of bytes to an `AsciiString` without checking for non-ASCII characters.
91     ///
92     /// # Safety
93     /// This function is unsafe because it does not check that the bytes passed to it are valid
94     /// ASCII characters. If this constraint is violated, it may cause memory unsafety issues with
95     /// future of the `AsciiString`, as the rest of this library assumes that `AsciiString`s are
96     /// ASCII encoded.
97     #[inline]
from_ascii_unchecked<B>(bytes: B) -> Self where B: Into<Vec<u8>>,98     pub unsafe fn from_ascii_unchecked<B>(bytes: B) -> Self
99     where
100         B: Into<Vec<u8>>,
101     {
102         let mut bytes = bytes.into();
103         let vec = Vec::from_raw_parts(
104             bytes.as_mut_ptr() as *mut AsciiChar,
105             bytes.len(),
106             bytes.capacity(),
107         );
108         mem::forget(bytes);
109         AsciiString { vec: vec }
110     }
111 
112     /// Converts anything that can represent a byte buffer into an `AsciiString`.
113     ///
114     /// # Failure
115     /// Returns the byte buffer if not all of the bytes are ASCII characters.
116     ///
117     /// # Examples
118     /// ```
119     /// # use ascii::AsciiString;
120     /// let foo = AsciiString::from_ascii("foo".to_string()).unwrap();
121     /// let err = AsciiString::from_ascii("Ŋ".to_string()).unwrap_err();
122     /// assert_eq!(foo.as_str(), "foo");
123     /// assert_eq!(err.into_source(), "Ŋ");
124     /// ```
from_ascii<B>(bytes: B) -> Result<AsciiString, FromAsciiError<B>> where B: Into<Vec<u8>> + AsRef<[u8]>,125     pub fn from_ascii<B>(bytes: B) -> Result<AsciiString, FromAsciiError<B>>
126     where
127         B: Into<Vec<u8>> + AsRef<[u8]>,
128     {
129         unsafe {
130             match bytes.as_ref().as_ascii_str() {
131                 Ok(_) => Ok(AsciiString::from_ascii_unchecked(bytes)),
132                 Err(e) => Err(FromAsciiError {
133                     error: e,
134                     owner: bytes,
135                 }),
136             }
137         }
138     }
139 
140     /// Pushes the given ASCII string onto this ASCII string buffer.
141     ///
142     /// # Examples
143     /// ```
144     /// # use ascii::{AsciiString, AsAsciiStr};
145     /// use std::str::FromStr;
146     /// let mut s = AsciiString::from_str("foo").unwrap();
147     /// s.push_str("bar".as_ascii_str().unwrap());
148     /// assert_eq!(s, "foobar".as_ascii_str().unwrap());
149     /// ```
150     #[inline]
push_str(&mut self, string: &AsciiStr)151     pub fn push_str(&mut self, string: &AsciiStr) {
152         self.vec.extend(string.chars())
153     }
154 
155     /// Returns the number of bytes that this ASCII string buffer can hold without reallocating.
156     ///
157     /// # Examples
158     /// ```
159     /// # use ascii::AsciiString;
160     /// let s = String::with_capacity(10);
161     /// assert!(s.capacity() >= 10);
162     /// ```
163     #[inline]
capacity(&self) -> usize164     pub fn capacity(&self) -> usize {
165         self.vec.capacity()
166     }
167 
168     /// Reserves capacity for at least `additional` more bytes to be inserted in the given
169     /// `AsciiString`. The collection may reserve more space to avoid frequent reallocations.
170     ///
171     /// # Panics
172     /// Panics if the new capacity overflows `usize`.
173     ///
174     /// # Examples
175     /// ```
176     /// # use ascii::AsciiString;
177     /// let mut s = AsciiString::new();
178     /// s.reserve(10);
179     /// assert!(s.capacity() >= 10);
180     /// ```
181     #[inline]
reserve(&mut self, additional: usize)182     pub fn reserve(&mut self, additional: usize) {
183         self.vec.reserve(additional)
184     }
185 
186     /// Reserves the minimum capacity for exactly `additional` more bytes to be inserted in the
187     /// given `AsciiString`. Does nothing if the capacity is already sufficient.
188     ///
189     /// Note that the allocator may give the collection more space than it requests. Therefore
190     /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
191     /// insertions are expected.
192     ///
193     /// # Panics
194     /// Panics if the new capacity overflows `usize`.
195     ///
196     /// # Examples
197     /// ```
198     /// # use ascii::AsciiString;
199     /// let mut s = AsciiString::new();
200     /// s.reserve_exact(10);
201     /// assert!(s.capacity() >= 10);
202     /// ```
203     #[inline]
reserve_exact(&mut self, additional: usize)204     pub fn reserve_exact(&mut self, additional: usize) {
205         self.vec.reserve_exact(additional)
206     }
207 
208     /// Shrinks the capacity of this ASCII string buffer to match it's length.
209     ///
210     /// # Examples
211     /// ```
212     /// # use ascii::AsciiString;
213     /// use std::str::FromStr;
214     /// let mut s = AsciiString::from_str("foo").unwrap();
215     /// s.reserve(100);
216     /// assert!(s.capacity() >= 100);
217     /// s.shrink_to_fit();
218     /// assert_eq!(s.capacity(), 3);
219     /// ```
220     #[inline]
shrink_to_fit(&mut self)221     pub fn shrink_to_fit(&mut self) {
222         self.vec.shrink_to_fit()
223     }
224 
225     /// Adds the given ASCII character to the end of the ASCII string.
226     ///
227     /// # Examples
228     /// ```
229     /// # use ascii::{ AsciiChar, AsciiString};
230     /// let mut s = AsciiString::from_ascii("abc").unwrap();
231     /// s.push(AsciiChar::from('1').unwrap());
232     /// s.push(AsciiChar::from('2').unwrap());
233     /// s.push(AsciiChar::from('3').unwrap());
234     /// assert_eq!(s, "abc123");
235     /// ```
236     #[inline]
push(&mut self, ch: AsciiChar)237     pub fn push(&mut self, ch: AsciiChar) {
238         self.vec.push(ch)
239     }
240 
241     /// Shortens a ASCII string to the specified length.
242     ///
243     /// # Panics
244     /// Panics if `new_len` > current length.
245     ///
246     /// # Examples
247     /// ```
248     /// # use ascii::AsciiString;
249     /// let mut s = AsciiString::from_ascii("hello").unwrap();
250     /// s.truncate(2);
251     /// assert_eq!(s, "he");
252     /// ```
253     #[inline]
truncate(&mut self, new_len: usize)254     pub fn truncate(&mut self, new_len: usize) {
255         self.vec.truncate(new_len)
256     }
257 
258     /// Removes the last character from the ASCII string buffer and returns it.
259     /// Returns `None` if this string buffer is empty.
260     ///
261     /// # Examples
262     /// ```
263     /// # use ascii::AsciiString;
264     /// let mut s = AsciiString::from_ascii("foo").unwrap();
265     /// assert_eq!(s.pop().map(|c| c.as_char()), Some('o'));
266     /// assert_eq!(s.pop().map(|c| c.as_char()), Some('o'));
267     /// assert_eq!(s.pop().map(|c| c.as_char()), Some('f'));
268     /// assert_eq!(s.pop(), None);
269     /// ```
270     #[inline]
pop(&mut self) -> Option<AsciiChar>271     pub fn pop(&mut self) -> Option<AsciiChar> {
272         self.vec.pop()
273     }
274 
275     /// Removes the ASCII character at position `idx` from the buffer and returns it.
276     ///
277     /// # Warning
278     /// This is an O(n) operation as it requires copying every element in the buffer.
279     ///
280     /// # Panics
281     /// If `idx` is out of bounds this function will panic.
282     ///
283     /// # Examples
284     /// ```
285     /// # use ascii::AsciiString;
286     /// let mut s = AsciiString::from_ascii("foo").unwrap();
287     /// assert_eq!(s.remove(0).as_char(), 'f');
288     /// assert_eq!(s.remove(1).as_char(), 'o');
289     /// assert_eq!(s.remove(0).as_char(), 'o');
290     /// ```
291     #[inline]
remove(&mut self, idx: usize) -> AsciiChar292     pub fn remove(&mut self, idx: usize) -> AsciiChar {
293         self.vec.remove(idx)
294     }
295 
296     /// Inserts an ASCII character into the buffer at position `idx`.
297     ///
298     /// # Warning
299     /// This is an O(n) operation as it requires copying every element in the buffer.
300     ///
301     /// # Panics
302     /// If `idx` is out of bounds this function will panic.
303     ///
304     /// # Examples
305     /// ```
306     /// # use ascii::{AsciiString,AsciiChar};
307     /// let mut s = AsciiString::from_ascii("foo").unwrap();
308     /// s.insert(2, AsciiChar::b);
309     /// assert_eq!(s, "fobo");
310     /// ```
311     #[inline]
insert(&mut self, idx: usize, ch: AsciiChar)312     pub fn insert(&mut self, idx: usize, ch: AsciiChar) {
313         self.vec.insert(idx, ch)
314     }
315 
316     /// Returns the number of bytes in this ASCII string.
317     ///
318     /// # Examples
319     /// ```
320     /// # use ascii::AsciiString;
321     /// let s = AsciiString::from_ascii("foo").unwrap();
322     /// assert_eq!(s.len(), 3);
323     /// ```
324     #[inline]
len(&self) -> usize325     pub fn len(&self) -> usize {
326         self.vec.len()
327     }
328 
329     /// Returns true if the ASCII string contains zero bytes.
330     ///
331     /// # Examples
332     /// ```
333     /// # use ascii::{AsciiChar, AsciiString};
334     /// let mut s = AsciiString::new();
335     /// assert!(s.is_empty());
336     /// s.push(AsciiChar::from('a').unwrap());
337     /// assert!(!s.is_empty());
338     /// ```
339     #[inline]
is_empty(&self) -> bool340     pub fn is_empty(&self) -> bool {
341         self.len() == 0
342     }
343 
344     /// Truncates the ASCII string, setting length (but not capacity) to zero.
345     ///
346     /// # Examples
347     /// ```
348     /// # use ascii::AsciiString;
349     /// let mut s = AsciiString::from_ascii("foo").unwrap();
350     /// s.clear();
351     /// assert!(s.is_empty());
352     /// ```
353     #[inline]
clear(&mut self)354     pub fn clear(&mut self) {
355         self.vec.clear()
356     }
357 }
358 
359 impl Deref for AsciiString {
360     type Target = AsciiStr;
361 
362     #[inline]
deref(&self) -> &AsciiStr363     fn deref(&self) -> &AsciiStr {
364         self.vec.as_slice().as_ref()
365     }
366 }
367 
368 impl DerefMut for AsciiString {
369     #[inline]
deref_mut(&mut self) -> &mut AsciiStr370     fn deref_mut(&mut self) -> &mut AsciiStr {
371         self.vec.as_mut_slice().as_mut()
372     }
373 }
374 
375 impl PartialEq<str> for AsciiString {
376     #[inline]
eq(&self, other: &str) -> bool377     fn eq(&self, other: &str) -> bool {
378         **self == *other
379     }
380 }
381 
382 impl PartialEq<AsciiString> for str {
383     #[inline]
eq(&self, other: &AsciiString) -> bool384     fn eq(&self, other: &AsciiString) -> bool {
385         **other == *self
386     }
387 }
388 
389 macro_rules! impl_eq {
390     ($lhs:ty, $rhs:ty) => {
391         impl<'a> PartialEq<$rhs> for $lhs {
392             #[inline]
393             fn eq(&self, other: &$rhs) -> bool {
394                 PartialEq::eq(&**self, &**other)
395             }
396             #[inline]
397             fn ne(&self, other: &$rhs) -> bool {
398                 PartialEq::ne(&**self, &**other)
399             }
400         }
401     }
402 }
403 
404 impl_eq! { AsciiString, String }
405 impl_eq! { String, AsciiString }
406 impl_eq! { &'a AsciiStr, String }
407 impl_eq! { String, &'a AsciiStr }
408 impl_eq! { &'a AsciiStr, AsciiString }
409 impl_eq! { AsciiString, &'a AsciiStr }
410 impl_eq! { &'a str, AsciiString }
411 impl_eq! { AsciiString, &'a str }
412 
413 impl Borrow<AsciiStr> for AsciiString {
414     #[inline]
borrow(&self) -> &AsciiStr415     fn borrow(&self) -> &AsciiStr {
416         &*self
417     }
418 }
419 
420 impl BorrowMut<AsciiStr> for AsciiString {
421     #[inline]
borrow_mut(&mut self) -> &mut AsciiStr422     fn borrow_mut(&mut self) -> &mut AsciiStr {
423         &mut*self
424     }
425 }
426 
427 impl From<Vec<AsciiChar>> for AsciiString {
428     #[inline]
from(vec: Vec<AsciiChar>) -> Self429     fn from(vec: Vec<AsciiChar>) -> Self {
430         AsciiString { vec: vec }
431     }
432 }
433 
434 impl Into<Vec<u8>> for AsciiString {
into(self) -> Vec<u8>435     fn into(self) -> Vec<u8> {
436         unsafe {
437             let v = Vec::from_raw_parts(
438                 self.vec.as_ptr() as *mut u8,
439                 self.vec.len(),
440                 self.vec.capacity(),
441             );
442 
443             // We forget `self` to avoid freeing it at the end of the scope.
444             // Otherwise, the returned `Vec` would point to freed memory.
445             mem::forget(self);
446             v
447         }
448     }
449 }
450 
451 impl<'a> From<&'a AsciiStr> for AsciiString {
452     #[inline]
from(s: &'a AsciiStr) -> Self453     fn from(s: &'a AsciiStr) -> Self {
454         s.to_ascii_string()
455     }
456 }
457 
458 impl<'a> From<&'a [AsciiChar]> for AsciiString {
459     #[inline]
from(s: &'a [AsciiChar]) -> AsciiString460     fn from(s: &'a [AsciiChar]) -> AsciiString {
461         s.into_iter().map(|c| *c).collect()
462     }
463 }
464 
465 impl Into<String> for AsciiString {
466     #[inline]
into(self) -> String467     fn into(self) -> String {
468         unsafe { String::from_utf8_unchecked(self.into()) }
469     }
470 }
471 
472 impl<'a> From<Cow<'a,AsciiStr>> for AsciiString {
from(cow: Cow<'a,AsciiStr>) -> AsciiString473     fn from(cow: Cow<'a,AsciiStr>) -> AsciiString {
474         cow.into_owned()
475     }
476 }
477 
478 impl From<AsciiString> for Cow<'static,AsciiStr> {
from(string: AsciiString) -> Cow<'static,AsciiStr>479     fn from(string: AsciiString) -> Cow<'static,AsciiStr> {
480         Cow::Owned(string)
481     }
482 }
483 
484 impl<'a> From<&'a AsciiStr> for Cow<'a,AsciiStr> {
from(s: &'a AsciiStr) -> Cow<'a,AsciiStr>485     fn from(s: &'a AsciiStr) -> Cow<'a,AsciiStr> {
486         Cow::Borrowed(s)
487     }
488 }
489 
490 impl AsRef<AsciiStr> for AsciiString {
491     #[inline]
as_ref(&self) -> &AsciiStr492     fn as_ref(&self) -> &AsciiStr {
493         &*self
494     }
495 }
496 
497 impl AsRef<[AsciiChar]> for AsciiString {
498     #[inline]
as_ref(&self) -> &[AsciiChar]499     fn as_ref(&self) -> &[AsciiChar] {
500         &self.vec
501     }
502 }
503 
504 impl AsRef<[u8]> for AsciiString {
505     #[inline]
as_ref(&self) -> &[u8]506     fn as_ref(&self) -> &[u8] {
507         self.as_bytes()
508     }
509 }
510 
511 impl AsRef<str> for AsciiString {
512     #[inline]
as_ref(&self) -> &str513     fn as_ref(&self) -> &str {
514         self.as_str()
515     }
516 }
517 
518 impl AsMut<AsciiStr> for AsciiString {
519     #[inline]
as_mut(&mut self) -> &mut AsciiStr520     fn as_mut(&mut self) -> &mut AsciiStr {
521         &mut *self
522     }
523 }
524 
525 impl AsMut<[AsciiChar]> for AsciiString {
526     #[inline]
as_mut(&mut self) -> &mut [AsciiChar]527     fn as_mut(&mut self) -> &mut [AsciiChar] {
528         &mut self.vec
529     }
530 }
531 
532 impl FromStr for AsciiString {
533     type Err = AsAsciiStrError;
534 
from_str(s: &str) -> Result<AsciiString, AsAsciiStrError>535     fn from_str(s: &str) -> Result<AsciiString, AsAsciiStrError> {
536         s.as_ascii_str().map(AsciiStr::to_ascii_string)
537     }
538 }
539 
540 impl fmt::Display for AsciiString {
541     #[inline]
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result542     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
543         fmt::Display::fmt(&**self, f)
544     }
545 }
546 
547 impl fmt::Debug for AsciiString {
548     #[inline]
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result549     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
550         fmt::Debug::fmt(&**self, f)
551     }
552 }
553 
554 /// Please note that the `std::fmt::Result` returned by these methods does not support
555 /// transmission of an error other than that an error occurred.
556 impl fmt::Write for AsciiString {
write_str(&mut self, s: &str) -> fmt::Result557     fn write_str(&mut self, s: &str) -> fmt::Result {
558         let astr = try!(AsciiStr::from_ascii(s).map_err(|_| fmt::Error));
559         self.push_str(astr);
560         Ok(())
561     }
562 
write_char(&mut self, c: char) -> fmt::Result563     fn write_char(&mut self, c: char) -> fmt::Result {
564         let achar = try!(AsciiChar::from(c).map_err(|_| fmt::Error));
565         self.push(achar);
566         Ok(())
567     }
568 }
569 
570 impl FromIterator<AsciiChar> for AsciiString {
from_iter<I: IntoIterator<Item = AsciiChar>>(iter: I) -> AsciiString571     fn from_iter<I: IntoIterator<Item = AsciiChar>>(iter: I) -> AsciiString {
572         let mut buf = AsciiString::new();
573         buf.extend(iter);
574         buf
575     }
576 }
577 
578 impl<'a> FromIterator<&'a AsciiStr> for AsciiString {
from_iter<I: IntoIterator<Item = &'a AsciiStr>>(iter: I) -> AsciiString579     fn from_iter<I: IntoIterator<Item = &'a AsciiStr>>(iter: I) -> AsciiString {
580         let mut buf = AsciiString::new();
581         buf.extend(iter);
582         buf
583     }
584 }
585 
586 impl<'a> FromIterator<Cow<'a, AsciiStr>> for AsciiString {
from_iter<I: IntoIterator<Item = Cow<'a, AsciiStr>>>(iter: I) -> AsciiString587     fn from_iter<I: IntoIterator<Item = Cow<'a, AsciiStr>>>(iter: I) -> AsciiString {
588         let mut buf = AsciiString::new();
589         buf.extend(iter);
590         buf
591     }
592 }
593 
594 impl Extend<AsciiChar> for AsciiString {
extend<I: IntoIterator<Item = AsciiChar>>(&mut self, iterable: I)595     fn extend<I: IntoIterator<Item = AsciiChar>>(&mut self, iterable: I) {
596         let iterator = iterable.into_iter();
597         let (lower_bound, _) = iterator.size_hint();
598         self.reserve(lower_bound);
599         for ch in iterator {
600             self.push(ch)
601         }
602     }
603 }
604 
605 impl<'a> Extend<&'a AsciiChar> for AsciiString {
extend<I: IntoIterator<Item = &'a AsciiChar>>(&mut self, iter: I)606     fn extend<I: IntoIterator<Item = &'a AsciiChar>>(&mut self, iter: I) {
607         self.extend(iter.into_iter().cloned())
608     }
609 }
610 
611 impl<'a> Extend<&'a AsciiStr> for AsciiString {
extend<I: IntoIterator<Item = &'a AsciiStr>>(&mut self, iterable: I)612     fn extend<I: IntoIterator<Item = &'a AsciiStr>>(&mut self, iterable: I) {
613         let iterator = iterable.into_iter();
614         let (lower_bound, _) = iterator.size_hint();
615         self.reserve(lower_bound);
616         for s in iterator {
617             self.push_str(s)
618         }
619     }
620 }
621 
622 impl<'a> Extend<Cow<'a, AsciiStr>> for AsciiString {
extend<I: IntoIterator<Item = Cow<'a,AsciiStr>>>(&mut self, iterable: I)623     fn extend<I: IntoIterator<Item = Cow<'a,AsciiStr>>>(&mut self, iterable: I) {
624         let iterator = iterable.into_iter();
625         let (lower_bound, _) = iterator.size_hint();
626         self.reserve(lower_bound);
627         for s in iterator {
628             self.push_str(&*s);
629         }
630     }
631 }
632 
633 impl<'a> Add<&'a AsciiStr> for AsciiString {
634     type Output = AsciiString;
635 
636     #[inline]
add(mut self, other: &AsciiStr) -> AsciiString637     fn add(mut self, other: &AsciiStr) -> AsciiString {
638         self.push_str(other);
639         self
640     }
641 }
642 
643 impl<'a> AddAssign<&'a AsciiStr> for AsciiString {
644     #[inline]
add_assign(&mut self, other: &AsciiStr)645     fn add_assign(&mut self, other: &AsciiStr) {
646         self.push_str(other);
647     }
648 }
649 
650 impl<T> Index<T> for AsciiString
651 where
652     AsciiStr: Index<T>,
653 {
654     type Output = <AsciiStr as Index<T>>::Output;
655 
656     #[inline]
index(&self, index: T) -> &<AsciiStr as Index<T>>::Output657     fn index(&self, index: T) -> &<AsciiStr as Index<T>>::Output {
658         &(**self)[index]
659     }
660 }
661 
662 impl<T> IndexMut<T> for AsciiString
663 where
664     AsciiStr: IndexMut<T>,
665 {
666     #[inline]
index_mut(&mut self, index: T) -> &mut <AsciiStr as Index<T>>::Output667     fn index_mut(&mut self, index: T) -> &mut <AsciiStr as Index<T>>::Output {
668         &mut (**self)[index]
669     }
670 }
671 
672 
673 /// A possible error value when converting an `AsciiString` from a byte vector or string.
674 /// It wraps an `AsAsciiStrError` which you can get through the `ascii_error()` method.
675 ///
676 /// This is the error type for `AsciiString::from_ascii()` and
677 /// `IntoAsciiString::into_ascii_string()`. They will never clone or touch the content of the
678 /// original type; It can be extracted by the `into_source` method.
679 ///
680 /// #Examples
681 /// ```
682 /// # use ascii::IntoAsciiString;
683 /// let err = "bø!".to_string().into_ascii_string().unwrap_err();
684 /// assert_eq!(err.ascii_error().valid_up_to(), 1);
685 /// assert_eq!(err.into_source(), "bø!".to_string());
686 /// ```
687 #[derive(Clone, Copy, PartialEq, Eq)]
688 pub struct FromAsciiError<O> {
689     error: AsAsciiStrError,
690     owner: O,
691 }
692 impl<O> FromAsciiError<O> {
693     /// Get the position of the first non-ASCII byte or character.
694     #[inline]
ascii_error(&self) -> AsAsciiStrError695     pub fn ascii_error(&self) -> AsAsciiStrError {
696         self.error
697     }
698     /// Get back the original, unmodified type.
699     #[inline]
into_source(self) -> O700     pub fn into_source(self) -> O {
701         self.owner
702     }
703 }
704 impl<O> fmt::Debug for FromAsciiError<O> {
705     #[inline]
fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result706     fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
707         fmt::Debug::fmt(&self.error, fmtr)
708     }
709 }
710 impl<O> fmt::Display for FromAsciiError<O> {
711     #[inline]
fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result712     fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
713         fmt::Display::fmt(&self.error, fmtr)
714     }
715 }
716 impl<O: Any> Error for FromAsciiError<O> {
717     #[inline]
description(&self) -> &str718     fn description(&self) -> &str {
719         self.error.description()
720     }
721     /// Always returns an `AsAsciiStrError`
cause(&self) -> Option<&Error>722     fn cause(&self) -> Option<&Error> {
723         Some(&self.error as &Error)
724     }
725 }
726 
727 
728 /// Convert vectors into `AsciiString`.
729 pub trait IntoAsciiString: Sized {
730     /// Convert to `AsciiString` without checking for non-ASCII characters.
into_ascii_string_unchecked(self) -> AsciiString731     unsafe fn into_ascii_string_unchecked(self) -> AsciiString;
732     /// Convert to `AsciiString`.
into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>>733     fn into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>>;
734 }
735 
736 impl IntoAsciiString for Vec<AsciiChar> {
737     #[inline]
into_ascii_string_unchecked(self) -> AsciiString738     unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
739         AsciiString::from(self)
740     }
741     #[inline]
into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>>742     fn into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>> {
743         Ok(AsciiString::from(self))
744     }
745 }
746 
747 impl<'a> IntoAsciiString for &'a [AsciiChar] {
748     #[inline]
into_ascii_string_unchecked(self) -> AsciiString749     unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
750         AsciiString::from(self)
751     }
752     #[inline]
into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>>753     fn into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>> {
754         Ok(AsciiString::from(self))
755     }
756 }
757 
758 impl<'a> IntoAsciiString for &'a AsciiStr {
759     #[inline]
into_ascii_string_unchecked(self) -> AsciiString760     unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
761         AsciiString::from(self)
762     }
763     #[inline]
into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>>764     fn into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>> {
765         Ok(AsciiString::from(self))
766     }
767 }
768 
769 macro_rules! impl_into_ascii_string {
770     ('a, $wider:ty) => {
771         impl<'a> IntoAsciiString for $wider {
772             #[inline]
773             unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
774                 AsciiString::from_ascii_unchecked(self)
775             }
776 
777             #[inline]
778             fn into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>> {
779                 AsciiString::from_ascii(self)
780             }
781         }
782     };
783 
784     ($wider:ty) => {
785         impl IntoAsciiString for $wider {
786             #[inline]
787             unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
788                 AsciiString::from_ascii_unchecked(self)
789             }
790 
791             #[inline]
792             fn into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>> {
793                 AsciiString::from_ascii(self)
794             }
795         }
796     };
797 }
798 
799 impl_into_ascii_string!{AsciiString}
800 impl_into_ascii_string!{Vec<u8>}
801 impl_into_ascii_string!{'a, &'a [u8]}
802 impl_into_ascii_string!{String}
803 impl_into_ascii_string!{'a, &'a str}
804 
805 /// Note that the trailing null byte will be removed in the conversion.
806 impl IntoAsciiString for CString {
807     #[inline]
into_ascii_string_unchecked(self) -> AsciiString808     unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
809         AsciiString::from_ascii_unchecked(self.into_bytes())
810     }
811 
into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>>812     fn into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>> {
813         AsciiString::from_ascii(self.into_bytes_with_nul())
814             .map_err(|FromAsciiError { error, owner }| {
815                 FromAsciiError {
816                     owner: unsafe {
817                         // The null byte is preserved from the original
818                         // `CString`, so this is safe.
819                         CString::from_vec_unchecked(owner)
820                     },
821                     error: error,
822                 }
823             })
824             .map(|mut s| {
825                 let _nul = s.pop();
826                 debug_assert_eq!(_nul, Some(AsciiChar::Null));
827                 s
828             })
829     }
830 }
831 
832 /// Note that the trailing null byte will be removed in the conversion.
833 impl<'a> IntoAsciiString for &'a CStr {
834     #[inline]
into_ascii_string_unchecked(self) -> AsciiString835     unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
836         AsciiString::from_ascii_unchecked(self.to_bytes())
837     }
838 
into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>>839     fn into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>> {
840         AsciiString::from_ascii(self.to_bytes_with_nul())
841             .map_err(|FromAsciiError { error, owner }| {
842                 FromAsciiError {
843                     owner: unsafe {
844                         CStr::from_ptr(owner.as_ptr() as *const _)
845                     },
846                     error: error,
847                 }
848             })
849             .map(|mut s| {
850                 let _nul = s.pop();
851                 debug_assert_eq!(_nul, Some(AsciiChar::Null));
852                 s
853             })
854     }
855 }
856 
857 impl<'a, B: ?Sized> IntoAsciiString for Cow<'a, B>
858 where
859     B: 'a + ToOwned,
860     &'a B: IntoAsciiString,
861     <B as ToOwned>::Owned: IntoAsciiString,
862 {
863     #[inline]
into_ascii_string_unchecked(self) -> AsciiString864     unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
865         IntoAsciiString::into_ascii_string_unchecked(self.into_owned())
866     }
867 
into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>>868     fn into_ascii_string(self) -> Result<AsciiString, FromAsciiError<Self>> {
869         match self {
870             Cow::Owned(b) => {
871                 IntoAsciiString::into_ascii_string(b)
872                     .map_err(|FromAsciiError { error, owner }| {
873                         FromAsciiError {
874                             owner: Cow::Owned(owner),
875                             error: error,
876                         }
877                     })
878             }
879             Cow::Borrowed(b) => {
880                 IntoAsciiString::into_ascii_string(b)
881                     .map_err(|FromAsciiError { error, owner }| {
882                         FromAsciiError {
883                             owner: Cow::Borrowed(owner),
884                             error: error,
885                         }
886                     })
887             }
888         }
889     }
890 }
891 
892 #[cfg(feature = "quickcheck")]
893 impl Arbitrary for AsciiString {
arbitrary<G: Gen>(g: &mut G) -> Self894     fn arbitrary<G: Gen>(g: &mut G) -> Self {
895         let size = {
896             let s = g.size();
897             g.gen_range(0, s)
898         };
899         let mut s = AsciiString::with_capacity(size);
900         for _ in 0..size {
901             s.push(AsciiChar::arbitrary(g));
902         }
903         s
904     }
905 
shrink(&self) -> Box<Iterator<Item = Self>>906     fn shrink(&self) -> Box<Iterator<Item = Self>> {
907         let chars: Vec<AsciiChar> = self.as_slice().to_vec();
908         Box::new(chars.shrink().map(
909             |x| x.into_iter().collect::<AsciiString>(),
910         ))
911     }
912 }
913 
914 #[cfg(test)]
915 mod tests {
916     use std::str::FromStr;
917     use std::ffi::CString;
918     use AsciiChar;
919     use super::{AsciiString, IntoAsciiString};
920 
921     #[test]
into_string()922     fn into_string() {
923         let v = AsciiString::from_ascii(&[40_u8, 32, 59][..]).unwrap();
924         assert_eq!(Into::<String>::into(v), "( ;".to_string());
925     }
926 
927     #[test]
into_bytes()928     fn into_bytes() {
929         let v = AsciiString::from_ascii(&[40_u8, 32, 59][..]).unwrap();
930         assert_eq!(Into::<Vec<u8>>::into(v), vec![40_u8, 32, 59])
931     }
932 
933     #[test]
from_ascii_vec()934     fn from_ascii_vec() {
935         let vec = vec![AsciiChar::from('A').unwrap(), AsciiChar::from('B').unwrap()];
936         assert_eq!(AsciiString::from(vec), AsciiString::from_str("AB").unwrap());
937     }
938 
939     #[test]
from_cstring()940     fn from_cstring() {
941         let cstring = CString::new("baz").unwrap();
942         let ascii_str = cstring.clone().into_ascii_string().unwrap();
943         let expected_chars = &[AsciiChar::b, AsciiChar::a, AsciiChar::z];
944         assert_eq!(ascii_str.len(), 3);
945         assert_eq!(ascii_str.as_slice(), expected_chars);
946 
947         let ascii_str_unchecked = unsafe {
948             cstring.into_ascii_string_unchecked()
949         };
950         assert_eq!(ascii_str_unchecked.len(), 3);
951         assert_eq!(ascii_str_unchecked.as_slice(), expected_chars);
952 
953         let sparkle_heart_bytes = vec![240u8, 159, 146, 150];
954         let cstring = CString::new(sparkle_heart_bytes).unwrap();
955         let cstr = &*cstring;
956         let ascii_err = cstr.into_ascii_string().unwrap_err();
957         assert_eq!(ascii_err.into_source(), &*cstring);
958     }
959 
960     #[test]
fmt_ascii_string()961     fn fmt_ascii_string() {
962         let s = "abc".to_string().into_ascii_string().unwrap();
963         assert_eq!(format!("{}", s), "abc".to_string());
964         assert_eq!(format!("{:?}", s), "\"abc\"".to_string());
965     }
966 
967     #[test]
write_fmt()968     fn write_fmt() {
969         use std::{fmt, str};
970 
971         let mut s0 = AsciiString::new();
972         fmt::write(&mut s0, format_args!("Hello World")).unwrap();
973         assert_eq!(s0, "Hello World");
974 
975         let mut s1 = AsciiString::new();
976         fmt::write(&mut s1, format_args!("{}", 9)).unwrap();
977         assert_eq!(s1, "9");
978 
979         let mut s2 = AsciiString::new();
980         let sparkle_heart_bytes = [240, 159, 146, 150];
981         let sparkle_heart = str::from_utf8(&sparkle_heart_bytes).unwrap();
982         assert!(fmt::write(&mut s2, format_args!("{}", sparkle_heart)).is_err());
983     }
984 }
985