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