1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! String manipulation
13 //! For more details, see std::str
15 #![stable(feature = "rust1", since = "1.0.0")]
17 use self::pattern::Pattern;
18 use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
23 use iter::{Map, Cloned, FusedIterator};
24 use slice::{self, SliceIndex};
26 use intrinsics::align_offset;
30 /// A trait to abstract the idea of creating a new instance of a type from a
33 /// `FromStr`'s [`from_str`] method is often used implicitly, through
34 /// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
36 /// [`from_str`]: #tymethod.from_str
37 /// [`str`]: ../../std/primitive.str.html
38 /// [`parse`]: ../../std/primitive.str.html#method.parse
42 /// Basic implementation of `FromStr` on an example `Point` type:
45 /// use std::str::FromStr;
46 /// use std::num::ParseIntError;
48 /// #[derive(Debug, PartialEq)]
54 /// impl FromStr for Point {
55 /// type Err = ParseIntError;
57 /// fn from_str(s: &str) -> Result<Self, Self::Err> {
58 /// let coords: Vec<&str> = s.trim_matches(|p| p == '(' || p == ')' )
62 /// let x_fromstr = coords[0].parse::<i32>()?;
63 /// let y_fromstr = coords[1].parse::<i32>()?;
65 /// Ok(Point { x: x_fromstr, y: y_fromstr })
69 /// let p = Point::from_str("(1,2)");
70 /// assert_eq!(p.unwrap(), Point{ x: 1, y: 2} )
72 #[stable(feature = "rust1", since = "1.0.0")]
73 pub trait FromStr: Sized {
74 /// The associated error which can be returned from parsing.
75 #[stable(feature = "rust1", since = "1.0.0")]
78 /// Parses a string `s` to return a value of this type.
80 /// If parsing succeeds, return the value inside `Ok`, otherwise
81 /// when the string is ill-formatted return an error specific to the
82 /// inside `Err`. The error type is specific to implementation of the trait.
86 /// Basic usage with [`i32`][ithirtytwo], a type that implements `FromStr`:
88 /// [ithirtytwo]: ../../std/primitive.i32.html
91 /// use std::str::FromStr;
94 /// let x = i32::from_str(s).unwrap();
98 #[stable(feature = "rust1", since = "1.0.0")]
99 fn from_str(s: &str) -> Result<Self, Self::Err>;
102 #[stable(feature = "rust1", since = "1.0.0")]
103 impl FromStr for bool {
104 type Err = ParseBoolError;
106 /// Parse a `bool` from a string.
108 /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not
109 /// actually be parseable.
114 /// use std::str::FromStr;
116 /// assert_eq!(FromStr::from_str("true"), Ok(true));
117 /// assert_eq!(FromStr::from_str("false"), Ok(false));
118 /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
121 /// Note, in many cases, the `.parse()` method on `str` is more proper.
124 /// assert_eq!("true".parse(), Ok(true));
125 /// assert_eq!("false".parse(), Ok(false));
126 /// assert!("not even a boolean".parse::<bool>().is_err());
129 fn from_str(s: &str) -> Result<bool, ParseBoolError> {
132 "false" => Ok(false),
133 _ => Err(ParseBoolError { _priv: () }),
138 /// An error returned when parsing a `bool` using [`from_str`] fails
140 /// [`from_str`]: ../../std/primitive.bool.html#method.from_str
141 #[derive(Debug, Clone, PartialEq, Eq)]
142 #[stable(feature = "rust1", since = "1.0.0")]
143 pub struct ParseBoolError { _priv: () }
145 #[stable(feature = "rust1", since = "1.0.0")]
146 impl fmt::Display for ParseBoolError {
147 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
148 "provided string was not `true` or `false`".fmt(f)
153 Section: Creating a string
156 /// Errors which can occur when attempting to interpret a sequence of [`u8`]
159 /// [`u8`]: ../../std/primitive.u8.html
161 /// As such, the `from_utf8` family of functions and methods for both [`String`]s
162 /// and [`&str`]s make use of this error, for example.
164 /// [`String`]: ../../std/string/struct.String.html#method.from_utf8
165 /// [`&str`]: ../../std/str/fn.from_utf8.html
166 #[derive(Copy, Eq, PartialEq, Clone, Debug)]
167 #[stable(feature = "rust1", since = "1.0.0")]
168 pub struct Utf8Error {
170 error_len: Option<u8>,
174 /// Returns the index in the given string up to which valid UTF-8 was
177 /// It is the maximum index such that `from_utf8(&input[..index])`
178 /// would return `Ok(_)`.
187 /// // some invalid bytes, in a vector
188 /// let sparkle_heart = vec![0, 159, 146, 150];
190 /// // std::str::from_utf8 returns a Utf8Error
191 /// let error = str::from_utf8(&sparkle_heart).unwrap_err();
193 /// // the second byte is invalid here
194 /// assert_eq!(1, error.valid_up_to());
196 #[stable(feature = "utf8_error", since = "1.5.0")]
197 pub fn valid_up_to(&self) -> usize { self.valid_up_to }
199 /// Provide more information about the failure:
201 /// * `None`: the end of the input was reached unexpectedly.
202 /// `self.valid_up_to()` is 1 to 3 bytes from the end of the input.
203 /// If a byte stream (such as a file or a network socket) is being decoded incrementally,
204 /// this could be a valid `char` whose UTF-8 byte sequence is spanning multiple chunks.
206 /// * `Some(len)`: an unexpected byte was encountered.
207 /// The length provided is that of the invalid byte sequence
208 /// that starts at the index given by `valid_up_to()`.
209 /// Decoding should resume after that sequence
210 /// (after inserting a U+FFFD REPLACEMENT CHARACTER) in case of lossy decoding.
211 #[stable(feature = "utf8_error_error_len", since = "1.20.0")]
212 pub fn error_len(&self) -> Option<usize> {
213 self.error_len.map(|len| len as usize)
217 /// Converts a slice of bytes to a string slice.
219 /// A string slice ([`&str`]) is made of bytes ([`u8`]), and a byte slice
220 /// ([`&[u8]`][byteslice]) is made of bytes, so this function converts between
221 /// the two. Not all byte slices are valid string slices, however: [`&str`] requires
222 /// that it is valid UTF-8. `from_utf8()` checks to ensure that the bytes are valid
223 /// UTF-8, and then does the conversion.
225 /// [`&str`]: ../../std/primitive.str.html
226 /// [`u8`]: ../../std/primitive.u8.html
227 /// [byteslice]: ../../std/primitive.slice.html
229 /// If you are sure that the byte slice is valid UTF-8, and you don't want to
230 /// incur the overhead of the validity check, there is an unsafe version of
231 /// this function, [`from_utf8_unchecked`][fromutf8u], which has the same
232 /// behavior but skips the check.
234 /// [fromutf8u]: fn.from_utf8_unchecked.html
236 /// If you need a `String` instead of a `&str`, consider
237 /// [`String::from_utf8`][string].
239 /// [string]: ../../std/string/struct.String.html#method.from_utf8
241 /// Because you can stack-allocate a `[u8; N]`, and you can take a
242 /// [`&[u8]`][byteslice] of it, this function is one way to have a
243 /// stack-allocated string. There is an example of this in the
244 /// examples section below.
246 /// [byteslice]: ../../std/primitive.slice.html
250 /// Returns `Err` if the slice is not UTF-8 with a description as to why the
251 /// provided slice is not UTF-8.
260 /// // some bytes, in a vector
261 /// let sparkle_heart = vec![240, 159, 146, 150];
263 /// // We know these bytes are valid, so just use `unwrap()`.
264 /// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap();
266 /// assert_eq!("💖", sparkle_heart);
274 /// // some invalid bytes, in a vector
275 /// let sparkle_heart = vec![0, 159, 146, 150];
277 /// assert!(str::from_utf8(&sparkle_heart).is_err());
280 /// See the docs for [`Utf8Error`][error] for more details on the kinds of
281 /// errors that can be returned.
283 /// [error]: struct.Utf8Error.html
285 /// A "stack allocated string":
290 /// // some bytes, in a stack-allocated array
291 /// let sparkle_heart = [240, 159, 146, 150];
293 /// // We know these bytes are valid, so just use `unwrap()`.
294 /// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap();
296 /// assert_eq!("💖", sparkle_heart);
298 #[stable(feature = "rust1", since = "1.0.0")]
299 pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
300 run_utf8_validation(v)?;
301 Ok(unsafe { from_utf8_unchecked(v) })
304 /// Converts a mutable slice of bytes to a mutable string slice.
313 /// // "Hello, Rust!" as a mutable vector
314 /// let mut hellorust = vec![72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33];
316 /// // As we know these bytes are valid, we can use `unwrap()`
317 /// let outstr = str::from_utf8_mut(&mut hellorust).unwrap();
319 /// assert_eq!("Hello, Rust!", outstr);
327 /// // Some invalid bytes in a mutable vector
328 /// let mut invalid = vec![128, 223];
330 /// assert!(str::from_utf8_mut(&mut invalid).is_err());
332 /// See the docs for [`Utf8Error`][error] for more details on the kinds of
333 /// errors that can be returned.
335 /// [error]: struct.Utf8Error.html
336 #[stable(feature = "str_mut_extras", since = "1.20.0")]
337 pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
338 run_utf8_validation(v)?;
339 Ok(unsafe { from_utf8_unchecked_mut(v) })
342 /// Forms a str from a pointer and a length.
344 /// The `len` argument is the number of bytes in the string.
348 /// This function is unsafe as there is no guarantee that the given pointer is
349 /// valid for `len` bytes, nor whether the lifetime inferred is a suitable
350 /// lifetime for the returned str.
352 /// The data must be valid UTF-8
354 /// `p` must be non-null, even for zero-length strs, because non-zero bits
355 /// are required to distinguish between a zero-length str within `Some()`
356 /// from `None`. `p` can be a bogus non-dereferencable pointer, such as `0x1`,
357 /// for zero-length strs, though.
361 /// The lifetime for the returned str is inferred from its usage. To
362 /// prevent accidental misuse, it's suggested to tie the lifetime to whichever
363 /// source lifetime is safe in the context, such as by providing a helper
364 /// function taking the lifetime of a host value for the str, or by explicit
366 /// Performs the same functionality as `from_raw_parts`, except that a mutable
369 unsafe fn from_raw_parts_mut<'a>(p: *mut u8, len: usize) -> &'a mut str {
370 from_utf8_unchecked_mut(slice::from_raw_parts_mut(p, len))
373 /// Converts a slice of bytes to a string slice without checking
374 /// that the string contains valid UTF-8.
376 /// See the safe version, [`from_utf8`][fromutf8], for more information.
378 /// [fromutf8]: fn.from_utf8.html
382 /// This function is unsafe because it does not check that the bytes passed to
383 /// it are valid UTF-8. If this constraint is violated, undefined behavior
384 /// results, as the rest of Rust assumes that [`&str`]s are valid UTF-8.
386 /// [`&str`]: ../../std/primitive.str.html
395 /// // some bytes, in a vector
396 /// let sparkle_heart = vec![240, 159, 146, 150];
398 /// let sparkle_heart = unsafe {
399 /// str::from_utf8_unchecked(&sparkle_heart)
402 /// assert_eq!("💖", sparkle_heart);
405 #[stable(feature = "rust1", since = "1.0.0")]
406 pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
410 /// Converts a slice of bytes to a string slice without checking
411 /// that the string contains valid UTF-8; mutable version.
413 /// See the immutable version, [`from_utf8_unchecked()`][fromutf8], for more information.
415 /// [fromutf8]: fn.from_utf8_unchecked.html
424 /// let mut heart = vec![240, 159, 146, 150];
425 /// let heart = unsafe { str::from_utf8_unchecked_mut(&mut heart) };
427 /// assert_eq!("💖", heart);
430 #[stable(feature = "str_mut_extras", since = "1.20.0")]
431 pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
435 #[stable(feature = "rust1", since = "1.0.0")]
436 impl fmt::Display for Utf8Error {
437 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
438 if let Some(error_len) = self.error_len {
439 write!(f, "invalid utf-8 sequence of {} bytes from index {}",
440 error_len, self.valid_up_to)
442 write!(f, "incomplete utf-8 byte sequence from index {}", self.valid_up_to)
451 /// An iterator over the [`char`]s of a string slice.
453 /// [`char`]: ../../std/primitive.char.html
455 /// This struct is created by the [`chars`] method on [`str`].
456 /// See its documentation for more.
458 /// [`chars`]: ../../std/primitive.str.html#method.chars
459 /// [`str`]: ../../std/primitive.str.html
460 #[derive(Clone, Debug)]
461 #[stable(feature = "rust1", since = "1.0.0")]
462 pub struct Chars<'a> {
463 iter: slice::Iter<'a, u8>
466 /// Returns the initial codepoint accumulator for the first byte.
467 /// The first byte is special, only want bottom 5 bits for width 2, 4 bits
468 /// for width 3, and 3 bits for width 4.
470 fn utf8_first_byte(byte: u8, width: u32) -> u32 { (byte & (0x7F >> width)) as u32 }
472 /// Returns the value of `ch` updated with continuation byte `byte`.
474 fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 { (ch << 6) | (byte & CONT_MASK) as u32 }
476 /// Checks whether the byte is a UTF-8 continuation byte (i.e. starts with the
479 fn utf8_is_cont_byte(byte: u8) -> bool { (byte & !CONT_MASK) == TAG_CONT_U8 }
482 fn unwrap_or_0(opt: Option<&u8>) -> u8 {
489 /// Reads the next code point out of a byte iterator (assuming a
490 /// UTF-8-like encoding).
491 #[unstable(feature = "str_internals", issue = "0")]
493 pub fn next_code_point<'a, I: Iterator<Item = &'a u8>>(bytes: &mut I) -> Option<u32> {
495 let x = match bytes.next() {
497 Some(&next_byte) if next_byte < 128 => return Some(next_byte as u32),
498 Some(&next_byte) => next_byte,
501 // Multibyte case follows
502 // Decode from a byte combination out of: [[[x y] z] w]
503 // NOTE: Performance is sensitive to the exact formulation here
504 let init = utf8_first_byte(x, 2);
505 let y = unwrap_or_0(bytes.next());
506 let mut ch = utf8_acc_cont_byte(init, y);
509 // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
510 let z = unwrap_or_0(bytes.next());
511 let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z);
512 ch = init << 12 | y_z;
515 // use only the lower 3 bits of `init`
516 let w = unwrap_or_0(bytes.next());
517 ch = (init & 7) << 18 | utf8_acc_cont_byte(y_z, w);
524 /// Reads the last code point out of a byte iterator (assuming a
525 /// UTF-8-like encoding).
527 fn next_code_point_reverse<'a, I>(bytes: &mut I) -> Option<u32>
528 where I: DoubleEndedIterator<Item = &'a u8>,
531 let w = match bytes.next_back() {
533 Some(&next_byte) if next_byte < 128 => return Some(next_byte as u32),
534 Some(&back_byte) => back_byte,
537 // Multibyte case follows
538 // Decode from a byte combination out of: [x [y [z w]]]
540 let z = unwrap_or_0(bytes.next_back());
541 ch = utf8_first_byte(z, 2);
542 if utf8_is_cont_byte(z) {
543 let y = unwrap_or_0(bytes.next_back());
544 ch = utf8_first_byte(y, 3);
545 if utf8_is_cont_byte(y) {
546 let x = unwrap_or_0(bytes.next_back());
547 ch = utf8_first_byte(x, 4);
548 ch = utf8_acc_cont_byte(ch, y);
550 ch = utf8_acc_cont_byte(ch, z);
552 ch = utf8_acc_cont_byte(ch, w);
557 #[stable(feature = "rust1", since = "1.0.0")]
558 impl<'a> Iterator for Chars<'a> {
562 fn next(&mut self) -> Option<char> {
563 next_code_point(&mut self.iter).map(|ch| {
564 // str invariant says `ch` is a valid Unicode Scalar Value
566 char::from_u32_unchecked(ch)
572 fn count(self) -> usize {
573 // length in `char` is equal to the number of non-continuation bytes
574 let bytes_len = self.iter.len();
575 let mut cont_bytes = 0;
576 for &byte in self.iter {
577 cont_bytes += utf8_is_cont_byte(byte) as usize;
579 bytes_len - cont_bytes
583 fn size_hint(&self) -> (usize, Option<usize>) {
584 let len = self.iter.len();
585 // `(len + 3)` can't overflow, because we know that the `slice::Iter`
586 // belongs to a slice in memory which has a maximum length of
587 // `isize::MAX` (that's well below `usize::MAX`).
588 ((len + 3) / 4, Some(len))
592 fn last(mut self) -> Option<char> {
593 // No need to go through the entire string.
598 #[stable(feature = "rust1", since = "1.0.0")]
599 impl<'a> DoubleEndedIterator for Chars<'a> {
601 fn next_back(&mut self) -> Option<char> {
602 next_code_point_reverse(&mut self.iter).map(|ch| {
603 // str invariant says `ch` is a valid Unicode Scalar Value
605 char::from_u32_unchecked(ch)
611 #[unstable(feature = "fused", issue = "35602")]
612 impl<'a> FusedIterator for Chars<'a> {}
615 /// View the underlying data as a subslice of the original data.
617 /// This has the same lifetime as the original slice, and so the
618 /// iterator can continue to be used while this exists.
623 /// let mut chars = "abc".chars();
625 /// assert_eq!(chars.as_str(), "abc");
627 /// assert_eq!(chars.as_str(), "bc");
630 /// assert_eq!(chars.as_str(), "");
632 #[stable(feature = "iter_to_slice", since = "1.4.0")]
634 pub fn as_str(&self) -> &'a str {
635 unsafe { from_utf8_unchecked(self.iter.as_slice()) }
639 /// An iterator over the [`char`]s of a string slice, and their positions.
641 /// [`char`]: ../../std/primitive.char.html
643 /// This struct is created by the [`char_indices`] method on [`str`].
644 /// See its documentation for more.
646 /// [`char_indices`]: ../../std/primitive.str.html#method.char_indices
647 /// [`str`]: ../../std/primitive.str.html
648 #[derive(Clone, Debug)]
649 #[stable(feature = "rust1", since = "1.0.0")]
650 pub struct CharIndices<'a> {
655 #[stable(feature = "rust1", since = "1.0.0")]
656 impl<'a> Iterator for CharIndices<'a> {
657 type Item = (usize, char);
660 fn next(&mut self) -> Option<(usize, char)> {
661 let pre_len = self.iter.iter.len();
662 match self.iter.next() {
665 let index = self.front_offset;
666 let len = self.iter.iter.len();
667 self.front_offset += pre_len - len;
674 fn count(self) -> usize {
679 fn size_hint(&self) -> (usize, Option<usize>) {
680 self.iter.size_hint()
684 fn last(mut self) -> Option<(usize, char)> {
685 // No need to go through the entire string.
690 #[stable(feature = "rust1", since = "1.0.0")]
691 impl<'a> DoubleEndedIterator for CharIndices<'a> {
693 fn next_back(&mut self) -> Option<(usize, char)> {
694 match self.iter.next_back() {
697 let index = self.front_offset + self.iter.iter.len();
704 #[unstable(feature = "fused", issue = "35602")]
705 impl<'a> FusedIterator for CharIndices<'a> {}
707 impl<'a> CharIndices<'a> {
708 /// View the underlying data as a subslice of the original data.
710 /// This has the same lifetime as the original slice, and so the
711 /// iterator can continue to be used while this exists.
712 #[stable(feature = "iter_to_slice", since = "1.4.0")]
714 pub fn as_str(&self) -> &'a str {
719 /// An iterator over the bytes of a string slice.
721 /// This struct is created by the [`bytes`] method on [`str`].
722 /// See its documentation for more.
724 /// [`bytes`]: ../../std/primitive.str.html#method.bytes
725 /// [`str`]: ../../std/primitive.str.html
726 #[stable(feature = "rust1", since = "1.0.0")]
727 #[derive(Clone, Debug)]
728 pub struct Bytes<'a>(Cloned<slice::Iter<'a, u8>>);
730 #[stable(feature = "rust1", since = "1.0.0")]
731 impl<'a> Iterator for Bytes<'a> {
735 fn next(&mut self) -> Option<u8> {
740 fn size_hint(&self) -> (usize, Option<usize>) {
745 fn count(self) -> usize {
750 fn last(self) -> Option<Self::Item> {
755 fn nth(&mut self, n: usize) -> Option<Self::Item> {
760 fn all<F>(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool {
765 fn any<F>(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool {
770 fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
771 P: FnMut(&Self::Item) -> bool
773 self.0.find(predicate)
777 fn position<P>(&mut self, predicate: P) -> Option<usize> where
778 P: FnMut(Self::Item) -> bool
780 self.0.position(predicate)
784 fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
785 P: FnMut(Self::Item) -> bool
787 self.0.rposition(predicate)
791 #[stable(feature = "rust1", since = "1.0.0")]
792 impl<'a> DoubleEndedIterator for Bytes<'a> {
794 fn next_back(&mut self) -> Option<u8> {
799 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
800 P: FnMut(&Self::Item) -> bool
802 self.0.rfind(predicate)
806 #[stable(feature = "rust1", since = "1.0.0")]
807 impl<'a> ExactSizeIterator for Bytes<'a> {
809 fn len(&self) -> usize {
814 fn is_empty(&self) -> bool {
819 #[unstable(feature = "fused", issue = "35602")]
820 impl<'a> FusedIterator for Bytes<'a> {}
822 /// This macro generates a Clone impl for string pattern API
823 /// wrapper types of the form X<'a, P>
824 macro_rules! derive_pattern_clone {
825 (clone $t:ident with |$s:ident| $e:expr) => {
826 impl<'a, P: Pattern<'a>> Clone for $t<'a, P>
827 where P::Searcher: Clone
829 fn clone(&self) -> Self {
837 /// This macro generates two public iterator structs
838 /// wrapping a private internal one that makes use of the `Pattern` API.
840 /// For all patterns `P: Pattern<'a>` the following items will be
841 /// generated (generics omitted):
843 /// struct $forward_iterator($internal_iterator);
844 /// struct $reverse_iterator($internal_iterator);
846 /// impl Iterator for $forward_iterator
847 /// { /* internal ends up calling Searcher::next_match() */ }
849 /// impl DoubleEndedIterator for $forward_iterator
850 /// where P::Searcher: DoubleEndedSearcher
851 /// { /* internal ends up calling Searcher::next_match_back() */ }
853 /// impl Iterator for $reverse_iterator
854 /// where P::Searcher: ReverseSearcher
855 /// { /* internal ends up calling Searcher::next_match_back() */ }
857 /// impl DoubleEndedIterator for $reverse_iterator
858 /// where P::Searcher: DoubleEndedSearcher
859 /// { /* internal ends up calling Searcher::next_match() */ }
861 /// The internal one is defined outside the macro, and has almost the same
862 /// semantic as a DoubleEndedIterator by delegating to `pattern::Searcher` and
863 /// `pattern::ReverseSearcher` for both forward and reverse iteration.
865 /// "Almost", because a `Searcher` and a `ReverseSearcher` for a given
866 /// `Pattern` might not return the same elements, so actually implementing
867 /// `DoubleEndedIterator` for it would be incorrect.
868 /// (See the docs in `str::pattern` for more details)
870 /// However, the internal struct still represents a single ended iterator from
871 /// either end, and depending on pattern is also a valid double ended iterator,
872 /// so the two wrapper structs implement `Iterator`
873 /// and `DoubleEndedIterator` depending on the concrete pattern type, leading
874 /// to the complex impls seen above.
875 macro_rules! generate_pattern_iterators {
879 $(#[$forward_iterator_attribute:meta])*
880 struct $forward_iterator:ident;
884 $(#[$reverse_iterator_attribute:meta])*
885 struct $reverse_iterator:ident;
887 // Stability of all generated items
889 $(#[$common_stability_attribute:meta])*
891 // Internal almost-iterator that is being delegated to
893 $internal_iterator:ident yielding ($iterty:ty);
895 // Kind of delegation - either single ended or double ended
898 $(#[$forward_iterator_attribute])*
899 $(#[$common_stability_attribute])*
900 pub struct $forward_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>);
902 $(#[$common_stability_attribute])*
903 impl<'a, P: Pattern<'a>> fmt::Debug for $forward_iterator<'a, P>
904 where P::Searcher: fmt::Debug
906 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
907 f.debug_tuple(stringify!($forward_iterator))
913 $(#[$common_stability_attribute])*
914 impl<'a, P: Pattern<'a>> Iterator for $forward_iterator<'a, P> {
918 fn next(&mut self) -> Option<$iterty> {
923 $(#[$common_stability_attribute])*
924 impl<'a, P: Pattern<'a>> Clone for $forward_iterator<'a, P>
925 where P::Searcher: Clone
927 fn clone(&self) -> Self {
928 $forward_iterator(self.0.clone())
932 $(#[$reverse_iterator_attribute])*
933 $(#[$common_stability_attribute])*
934 pub struct $reverse_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>);
936 $(#[$common_stability_attribute])*
937 impl<'a, P: Pattern<'a>> fmt::Debug for $reverse_iterator<'a, P>
938 where P::Searcher: fmt::Debug
940 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
941 f.debug_tuple(stringify!($reverse_iterator))
947 $(#[$common_stability_attribute])*
948 impl<'a, P: Pattern<'a>> Iterator for $reverse_iterator<'a, P>
949 where P::Searcher: ReverseSearcher<'a>
954 fn next(&mut self) -> Option<$iterty> {
959 $(#[$common_stability_attribute])*
960 impl<'a, P: Pattern<'a>> Clone for $reverse_iterator<'a, P>
961 where P::Searcher: Clone
963 fn clone(&self) -> Self {
964 $reverse_iterator(self.0.clone())
968 #[unstable(feature = "fused", issue = "35602")]
969 impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
971 #[unstable(feature = "fused", issue = "35602")]
972 impl<'a, P: Pattern<'a>> FusedIterator for $reverse_iterator<'a, P>
973 where P::Searcher: ReverseSearcher<'a> {}
975 generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
977 $reverse_iterator, $iterty);
980 double ended; with $(#[$common_stability_attribute:meta])*,
981 $forward_iterator:ident,
982 $reverse_iterator:ident, $iterty:ty
984 $(#[$common_stability_attribute])*
985 impl<'a, P: Pattern<'a>> DoubleEndedIterator for $forward_iterator<'a, P>
986 where P::Searcher: DoubleEndedSearcher<'a>
989 fn next_back(&mut self) -> Option<$iterty> {
994 $(#[$common_stability_attribute])*
995 impl<'a, P: Pattern<'a>> DoubleEndedIterator for $reverse_iterator<'a, P>
996 where P::Searcher: DoubleEndedSearcher<'a>
999 fn next_back(&mut self) -> Option<$iterty> {
1005 single ended; with $(#[$common_stability_attribute:meta])*,
1006 $forward_iterator:ident,
1007 $reverse_iterator:ident, $iterty:ty
1011 derive_pattern_clone!{
1013 with |s| SplitInternal { matcher: s.matcher.clone(), ..*s }
1016 struct SplitInternal<'a, P: Pattern<'a>> {
1019 matcher: P::Searcher,
1020 allow_trailing_empty: bool,
1024 impl<'a, P: Pattern<'a>> fmt::Debug for SplitInternal<'a, P> where P::Searcher: fmt::Debug {
1025 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1026 f.debug_struct("SplitInternal")
1027 .field("start", &self.start)
1028 .field("end", &self.end)
1029 .field("matcher", &self.matcher)
1030 .field("allow_trailing_empty", &self.allow_trailing_empty)
1031 .field("finished", &self.finished)
1036 impl<'a, P: Pattern<'a>> SplitInternal<'a, P> {
1038 fn get_end(&mut self) -> Option<&'a str> {
1039 if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
1040 self.finished = true;
1042 let string = self.matcher.haystack().slice_unchecked(self.start, self.end);
1051 fn next(&mut self) -> Option<&'a str> {
1052 if self.finished { return None }
1054 let haystack = self.matcher.haystack();
1055 match self.matcher.next_match() {
1056 Some((a, b)) => unsafe {
1057 let elt = haystack.slice_unchecked(self.start, a);
1061 None => self.get_end(),
1066 fn next_back(&mut self) -> Option<&'a str>
1067 where P::Searcher: ReverseSearcher<'a>
1069 if self.finished { return None }
1071 if !self.allow_trailing_empty {
1072 self.allow_trailing_empty = true;
1073 match self.next_back() {
1074 Some(elt) if !elt.is_empty() => return Some(elt),
1075 _ => if self.finished { return None }
1079 let haystack = self.matcher.haystack();
1080 match self.matcher.next_match_back() {
1081 Some((a, b)) => unsafe {
1082 let elt = haystack.slice_unchecked(b, self.end);
1087 self.finished = true;
1088 Some(haystack.slice_unchecked(self.start, self.end))
1094 generate_pattern_iterators! {
1096 /// Created with the method [`split`].
1098 /// [`split`]: ../../std/primitive.str.html#method.split
1101 /// Created with the method [`rsplit`].
1103 /// [`rsplit`]: ../../std/primitive.str.html#method.rsplit
1106 #[stable(feature = "rust1", since = "1.0.0")]
1108 SplitInternal yielding (&'a str);
1109 delegate double ended;
1112 generate_pattern_iterators! {
1114 /// Created with the method [`split_terminator`].
1116 /// [`split_terminator`]: ../../std/primitive.str.html#method.split_terminator
1117 struct SplitTerminator;
1119 /// Created with the method [`rsplit_terminator`].
1121 /// [`rsplit_terminator`]: ../../std/primitive.str.html#method.rsplit_terminator
1122 struct RSplitTerminator;
1124 #[stable(feature = "rust1", since = "1.0.0")]
1126 SplitInternal yielding (&'a str);
1127 delegate double ended;
1130 derive_pattern_clone!{
1131 clone SplitNInternal
1132 with |s| SplitNInternal { iter: s.iter.clone(), ..*s }
1135 struct SplitNInternal<'a, P: Pattern<'a>> {
1136 iter: SplitInternal<'a, P>,
1137 /// The number of splits remaining
1141 impl<'a, P: Pattern<'a>> fmt::Debug for SplitNInternal<'a, P> where P::Searcher: fmt::Debug {
1142 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1143 f.debug_struct("SplitNInternal")
1144 .field("iter", &self.iter)
1145 .field("count", &self.count)
1150 impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> {
1152 fn next(&mut self) -> Option<&'a str> {
1155 1 => { self.count = 0; self.iter.get_end() }
1156 _ => { self.count -= 1; self.iter.next() }
1161 fn next_back(&mut self) -> Option<&'a str>
1162 where P::Searcher: ReverseSearcher<'a>
1166 1 => { self.count = 0; self.iter.get_end() }
1167 _ => { self.count -= 1; self.iter.next_back() }
1172 generate_pattern_iterators! {
1174 /// Created with the method [`splitn`].
1176 /// [`splitn`]: ../../std/primitive.str.html#method.splitn
1179 /// Created with the method [`rsplitn`].
1181 /// [`rsplitn`]: ../../std/primitive.str.html#method.rsplitn
1184 #[stable(feature = "rust1", since = "1.0.0")]
1186 SplitNInternal yielding (&'a str);
1187 delegate single ended;
1190 derive_pattern_clone!{
1191 clone MatchIndicesInternal
1192 with |s| MatchIndicesInternal(s.0.clone())
1195 struct MatchIndicesInternal<'a, P: Pattern<'a>>(P::Searcher);
1197 impl<'a, P: Pattern<'a>> fmt::Debug for MatchIndicesInternal<'a, P> where P::Searcher: fmt::Debug {
1198 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1199 f.debug_tuple("MatchIndicesInternal")
1205 impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
1207 fn next(&mut self) -> Option<(usize, &'a str)> {
1208 self.0.next_match().map(|(start, end)| unsafe {
1209 (start, self.0.haystack().slice_unchecked(start, end))
1214 fn next_back(&mut self) -> Option<(usize, &'a str)>
1215 where P::Searcher: ReverseSearcher<'a>
1217 self.0.next_match_back().map(|(start, end)| unsafe {
1218 (start, self.0.haystack().slice_unchecked(start, end))
1223 generate_pattern_iterators! {
1225 /// Created with the method [`match_indices`].
1227 /// [`match_indices`]: ../../std/primitive.str.html#method.match_indices
1228 struct MatchIndices;
1230 /// Created with the method [`rmatch_indices`].
1232 /// [`rmatch_indices`]: ../../std/primitive.str.html#method.rmatch_indices
1233 struct RMatchIndices;
1235 #[stable(feature = "str_match_indices", since = "1.5.0")]
1237 MatchIndicesInternal yielding ((usize, &'a str));
1238 delegate double ended;
1241 derive_pattern_clone!{
1242 clone MatchesInternal
1243 with |s| MatchesInternal(s.0.clone())
1246 struct MatchesInternal<'a, P: Pattern<'a>>(P::Searcher);
1248 impl<'a, P: Pattern<'a>> fmt::Debug for MatchesInternal<'a, P> where P::Searcher: fmt::Debug {
1249 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1250 f.debug_tuple("MatchesInternal")
1256 impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
1258 fn next(&mut self) -> Option<&'a str> {
1259 self.0.next_match().map(|(a, b)| unsafe {
1260 // Indices are known to be on utf8 boundaries
1261 self.0.haystack().slice_unchecked(a, b)
1266 fn next_back(&mut self) -> Option<&'a str>
1267 where P::Searcher: ReverseSearcher<'a>
1269 self.0.next_match_back().map(|(a, b)| unsafe {
1270 // Indices are known to be on utf8 boundaries
1271 self.0.haystack().slice_unchecked(a, b)
1276 generate_pattern_iterators! {
1278 /// Created with the method [`matches`].
1280 /// [`matches`]: ../../std/primitive.str.html#method.matches
1283 /// Created with the method [`rmatches`].
1285 /// [`rmatches`]: ../../std/primitive.str.html#method.rmatches
1288 #[stable(feature = "str_matches", since = "1.2.0")]
1290 MatchesInternal yielding (&'a str);
1291 delegate double ended;
1294 /// An iterator over the lines of a string, as string slices.
1296 /// This struct is created with the [`lines`] method on [`str`].
1297 /// See its documentation for more.
1299 /// [`lines`]: ../../std/primitive.str.html#method.lines
1300 /// [`str`]: ../../std/primitive.str.html
1301 #[stable(feature = "rust1", since = "1.0.0")]
1302 #[derive(Clone, Debug)]
1303 pub struct Lines<'a>(Map<SplitTerminator<'a, char>, LinesAnyMap>);
1305 #[stable(feature = "rust1", since = "1.0.0")]
1306 impl<'a> Iterator for Lines<'a> {
1307 type Item = &'a str;
1310 fn next(&mut self) -> Option<&'a str> {
1315 fn size_hint(&self) -> (usize, Option<usize>) {
1320 #[stable(feature = "rust1", since = "1.0.0")]
1321 impl<'a> DoubleEndedIterator for Lines<'a> {
1323 fn next_back(&mut self) -> Option<&'a str> {
1328 #[unstable(feature = "fused", issue = "35602")]
1329 impl<'a> FusedIterator for Lines<'a> {}
1331 /// Created with the method [`lines_any`].
1333 /// [`lines_any`]: ../../std/primitive.str.html#method.lines_any
1334 #[stable(feature = "rust1", since = "1.0.0")]
1335 #[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")]
1336 #[derive(Clone, Debug)]
1337 #[allow(deprecated)]
1338 pub struct LinesAny<'a>(Lines<'a>);
1340 /// A nameable, cloneable fn type
1344 impl<'a> Fn<(&'a str,)> for LinesAnyMap {
1346 extern "rust-call" fn call(&self, (line,): (&'a str,)) -> &'a str {
1348 if l > 0 && line.as_bytes()[l - 1] == b'\r' { &line[0 .. l - 1] }
1353 impl<'a> FnMut<(&'a str,)> for LinesAnyMap {
1355 extern "rust-call" fn call_mut(&mut self, (line,): (&'a str,)) -> &'a str {
1356 Fn::call(&*self, (line,))
1360 impl<'a> FnOnce<(&'a str,)> for LinesAnyMap {
1361 type Output = &'a str;
1364 extern "rust-call" fn call_once(self, (line,): (&'a str,)) -> &'a str {
1365 Fn::call(&self, (line,))
1369 #[stable(feature = "rust1", since = "1.0.0")]
1370 #[allow(deprecated)]
1371 impl<'a> Iterator for LinesAny<'a> {
1372 type Item = &'a str;
1375 fn next(&mut self) -> Option<&'a str> {
1380 fn size_hint(&self) -> (usize, Option<usize>) {
1385 #[stable(feature = "rust1", since = "1.0.0")]
1386 #[allow(deprecated)]
1387 impl<'a> DoubleEndedIterator for LinesAny<'a> {
1389 fn next_back(&mut self) -> Option<&'a str> {
1394 #[unstable(feature = "fused", issue = "35602")]
1395 #[allow(deprecated)]
1396 impl<'a> FusedIterator for LinesAny<'a> {}
1399 Section: Comparing strings
1402 /// Bytewise slice equality
1403 /// NOTE: This function is (ab)used in rustc::middle::trans::_match
1404 /// to compare &[u8] byte slices that are not necessarily valid UTF-8.
1407 fn eq_slice(a: &str, b: &str) -> bool {
1408 a.as_bytes() == b.as_bytes()
1412 Section: UTF-8 validation
1415 // use truncation to fit u64 into usize
1416 const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
1418 /// Returns `true` if any byte in the word `x` is nonascii (>= 128).
1420 fn contains_nonascii(x: usize) -> bool {
1421 (x & NONASCII_MASK) != 0
1424 /// Walks through `iter` checking that it's a valid UTF-8 sequence,
1425 /// returning `true` in that case, or, if it is invalid, `false` with
1426 /// `iter` reset such that it is pointing at the first byte in the
1427 /// invalid sequence.
1429 fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
1433 let usize_bytes = mem::size_of::<usize>();
1434 let ascii_block_size = 2 * usize_bytes;
1435 let blocks_end = if len >= ascii_block_size { len - ascii_block_size + 1 } else { 0 };
1438 let old_offset = index;
1440 ($error_len: expr) => {
1441 return Err(Utf8Error {
1442 valid_up_to: old_offset,
1443 error_len: $error_len,
1448 macro_rules! next { () => {{
1450 // we needed data, but there was none: error!
1457 let first = v[index];
1459 let w = UTF8_CHAR_WIDTH[first as usize];
1460 // 2-byte encoding is for codepoints \u{0080} to \u{07ff}
1461 // first C2 80 last DF BF
1462 // 3-byte encoding is for codepoints \u{0800} to \u{ffff}
1463 // first E0 A0 80 last EF BF BF
1464 // excluding surrogates codepoints \u{d800} to \u{dfff}
1465 // ED A0 80 to ED BF BF
1466 // 4-byte encoding is for codepoints \u{1000}0 to \u{10ff}ff
1467 // first F0 90 80 80 last F4 8F BF BF
1469 // Use the UTF-8 syntax from the RFC
1471 // https://tools.ietf.org/html/rfc3629
1473 // UTF8-2 = %xC2-DF UTF8-tail
1474 // UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
1475 // %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
1476 // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
1477 // %xF4 %x80-8F 2( UTF8-tail )
1479 2 => if next!() & !CONT_MASK != TAG_CONT_U8 {
1483 match (first, next!()) {
1484 (0xE0 , 0xA0 ... 0xBF) |
1485 (0xE1 ... 0xEC, 0x80 ... 0xBF) |
1486 (0xED , 0x80 ... 0x9F) |
1487 (0xEE ... 0xEF, 0x80 ... 0xBF) => {}
1490 if next!() & !CONT_MASK != TAG_CONT_U8 {
1495 match (first, next!()) {
1496 (0xF0 , 0x90 ... 0xBF) |
1497 (0xF1 ... 0xF3, 0x80 ... 0xBF) |
1498 (0xF4 , 0x80 ... 0x8F) => {}
1501 if next!() & !CONT_MASK != TAG_CONT_U8 {
1504 if next!() & !CONT_MASK != TAG_CONT_U8 {
1512 // Ascii case, try to skip forward quickly.
1513 // When the pointer is aligned, read 2 words of data per iteration
1514 // until we find a word containing a non-ascii byte.
1515 let ptr = v.as_ptr();
1516 let align = unsafe {
1517 // the offset is safe, because `index` is guaranteed inbounds
1518 align_offset(ptr.offset(index as isize) as *const (), usize_bytes)
1521 while index < blocks_end {
1523 let block = ptr.offset(index as isize) as *const usize;
1524 // break if there is a nonascii byte
1525 let zu = contains_nonascii(*block);
1526 let zv = contains_nonascii(*block.offset(1));
1531 index += ascii_block_size;
1533 // step from the point where the wordwise loop stopped
1534 while index < len && v[index] < 128 {
1546 // https://tools.ietf.org/html/rfc3629
1547 static UTF8_CHAR_WIDTH: [u8; 256] = [
1548 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1549 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
1550 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1551 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
1552 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1553 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
1554 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1555 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
1556 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1557 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
1558 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1559 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
1560 0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
1561 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
1562 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
1563 4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
1566 /// Given a first byte, determines how many bytes are in this UTF-8 character.
1567 #[unstable(feature = "str_internals", issue = "0")]
1569 pub fn utf8_char_width(b: u8) -> usize {
1570 return UTF8_CHAR_WIDTH[b as usize] as usize;
1573 /// Mask of the value bits of a continuation byte.
1574 const CONT_MASK: u8 = 0b0011_1111;
1575 /// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte.
1576 const TAG_CONT_U8: u8 = 0b1000_0000;
1579 Section: Trait implementations
1585 use slice::{self, SliceIndex};
1588 /// Implements ordering of strings.
1590 /// Strings are ordered lexicographically by their byte values. This orders Unicode code
1591 /// points based on their positions in the code charts. This is not necessarily the same as
1592 /// "alphabetical" order, which varies by language and locale. Sorting strings according to
1593 /// culturally-accepted standards requires locale-specific data that is outside the scope of
1595 #[stable(feature = "rust1", since = "1.0.0")]
1598 fn cmp(&self, other: &str) -> Ordering {
1599 self.as_bytes().cmp(other.as_bytes())
1603 #[stable(feature = "rust1", since = "1.0.0")]
1604 impl PartialEq for str {
1606 fn eq(&self, other: &str) -> bool {
1607 eq_slice(self, other)
1610 fn ne(&self, other: &str) -> bool { !(*self).eq(other) }
1613 #[stable(feature = "rust1", since = "1.0.0")]
1616 /// Implements comparison operations on strings.
1618 /// Strings are compared lexicographically by their byte values. This compares Unicode code
1619 /// points based on their positions in the code charts. This is not necessarily the same as
1620 /// "alphabetical" order, which varies by language and locale. Comparing strings according to
1621 /// culturally-accepted standards requires locale-specific data that is outside the scope of
1623 #[stable(feature = "rust1", since = "1.0.0")]
1624 impl PartialOrd for str {
1626 fn partial_cmp(&self, other: &str) -> Option<Ordering> {
1627 Some(self.cmp(other))
1631 /// Implements substring slicing with syntax `&self[begin .. end]`.
1633 /// Returns a slice of the given string from the byte range
1634 /// [`begin`..`end`).
1636 /// This operation is `O(1)`.
1640 /// Panics if `begin` or `end` does not point to the starting
1641 /// byte offset of a character (as defined by `is_char_boundary`).
1642 /// Requires that `begin <= end` and `end <= len` where `len` is the
1643 /// length of the string.
1648 /// let s = "Löwe 老虎 Léopard";
1649 /// assert_eq!(&s[0 .. 1], "L");
1651 /// assert_eq!(&s[1 .. 9], "öwe 老");
1653 /// // these will panic:
1654 /// // byte 2 lies within `ö`:
1657 /// // byte 8 lies within `老`
1660 /// // byte 100 is outside the string
1661 /// // &s[3 .. 100];
1663 #[stable(feature = "rust1", since = "1.0.0")]
1664 impl ops::Index<ops::Range<usize>> for str {
1667 fn index(&self, index: ops::Range<usize>) -> &str {
1672 /// Implements mutable substring slicing with syntax
1673 /// `&mut self[begin .. end]`.
1675 /// Returns a mutable slice of the given string from the byte range
1676 /// [`begin`..`end`).
1678 /// This operation is `O(1)`.
1682 /// Panics if `begin` or `end` does not point to the starting
1683 /// byte offset of a character (as defined by `is_char_boundary`).
1684 /// Requires that `begin <= end` and `end <= len` where `len` is the
1685 /// length of the string.
1686 #[stable(feature = "derefmut_for_string", since = "1.3.0")]
1687 impl ops::IndexMut<ops::Range<usize>> for str {
1689 fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str {
1690 index.index_mut(self)
1694 /// Implements substring slicing with syntax `&self[.. end]`.
1696 /// Returns a slice of the string from the beginning to byte offset
1699 /// Equivalent to `&self[0 .. end]`.
1700 #[stable(feature = "rust1", since = "1.0.0")]
1701 impl ops::Index<ops::RangeTo<usize>> for str {
1705 fn index(&self, index: ops::RangeTo<usize>) -> &str {
1710 /// Implements mutable substring slicing with syntax `&mut self[.. end]`.
1712 /// Returns a mutable slice of the string from the beginning to byte offset
1715 /// Equivalent to `&mut self[0 .. end]`.
1716 #[stable(feature = "derefmut_for_string", since = "1.3.0")]
1717 impl ops::IndexMut<ops::RangeTo<usize>> for str {
1719 fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str {
1720 index.index_mut(self)
1724 /// Implements substring slicing with syntax `&self[begin ..]`.
1726 /// Returns a slice of the string from byte offset `begin`
1727 /// to the end of the string.
1729 /// Equivalent to `&self[begin .. len]`.
1730 #[stable(feature = "rust1", since = "1.0.0")]
1731 impl ops::Index<ops::RangeFrom<usize>> for str {
1735 fn index(&self, index: ops::RangeFrom<usize>) -> &str {
1740 /// Implements mutable substring slicing with syntax `&mut self[begin ..]`.
1742 /// Returns a mutable slice of the string from byte offset `begin`
1743 /// to the end of the string.
1745 /// Equivalent to `&mut self[begin .. len]`.
1746 #[stable(feature = "derefmut_for_string", since = "1.3.0")]
1747 impl ops::IndexMut<ops::RangeFrom<usize>> for str {
1749 fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str {
1750 index.index_mut(self)
1754 /// Implements substring slicing with syntax `&self[..]`.
1756 /// Returns a slice of the whole string. This operation can
1759 /// Equivalent to `&self[0 .. len]`.
1760 #[stable(feature = "rust1", since = "1.0.0")]
1761 impl ops::Index<ops::RangeFull> for str {
1765 fn index(&self, _index: ops::RangeFull) -> &str {
1770 /// Implements mutable substring slicing with syntax `&mut self[..]`.
1772 /// Returns a mutable slice of the whole string. This operation can
1775 /// Equivalent to `&mut self[0 .. len]`.
1776 #[stable(feature = "derefmut_for_string", since = "1.3.0")]
1777 impl ops::IndexMut<ops::RangeFull> for str {
1779 fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str {
1784 #[unstable(feature = "inclusive_range",
1785 reason = "recently added, follows RFC",
1787 impl ops::Index<ops::RangeInclusive<usize>> for str {
1791 fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
1796 #[unstable(feature = "inclusive_range",
1797 reason = "recently added, follows RFC",
1799 impl ops::Index<ops::RangeToInclusive<usize>> for str {
1803 fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
1808 #[unstable(feature = "inclusive_range",
1809 reason = "recently added, follows RFC",
1811 impl ops::IndexMut<ops::RangeInclusive<usize>> for str {
1813 fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
1814 index.index_mut(self)
1817 #[unstable(feature = "inclusive_range",
1818 reason = "recently added, follows RFC",
1820 impl ops::IndexMut<ops::RangeToInclusive<usize>> for str {
1822 fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
1823 index.index_mut(self)
1827 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
1828 impl SliceIndex<str> for ops::RangeFull {
1831 fn get(self, slice: &str) -> Option<&Self::Output> {
1835 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
1839 unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
1843 unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
1847 fn index(self, slice: &str) -> &Self::Output {
1851 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
1856 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
1857 impl SliceIndex<str> for ops::Range<usize> {
1860 fn get(self, slice: &str) -> Option<&Self::Output> {
1861 if self.start <= self.end &&
1862 slice.is_char_boundary(self.start) &&
1863 slice.is_char_boundary(self.end) {
1864 Some(unsafe { self.get_unchecked(slice) })
1870 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
1871 if self.start <= self.end &&
1872 slice.is_char_boundary(self.start) &&
1873 slice.is_char_boundary(self.end) {
1874 Some(unsafe { self.get_unchecked_mut(slice) })
1880 unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
1881 let ptr = slice.as_ptr().offset(self.start as isize);
1882 let len = self.end - self.start;
1883 super::from_utf8_unchecked(slice::from_raw_parts(ptr, len))
1886 unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
1887 let ptr = slice.as_ptr().offset(self.start as isize);
1888 let len = self.end - self.start;
1889 super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
1892 fn index(self, slice: &str) -> &Self::Output {
1893 let (start, end) = (self.start, self.end);
1894 self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, start, end))
1897 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
1898 // is_char_boundary checks that the index is in [0, .len()]
1899 // canot reuse `get` as above, because of NLL trouble
1900 if self.start <= self.end &&
1901 slice.is_char_boundary(self.start) &&
1902 slice.is_char_boundary(self.end) {
1903 unsafe { self.get_unchecked_mut(slice) }
1905 super::slice_error_fail(slice, self.start, self.end)
1910 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
1911 impl SliceIndex<str> for ops::RangeTo<usize> {
1914 fn get(self, slice: &str) -> Option<&Self::Output> {
1915 if slice.is_char_boundary(self.end) {
1916 Some(unsafe { self.get_unchecked(slice) })
1922 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
1923 if slice.is_char_boundary(self.end) {
1924 Some(unsafe { self.get_unchecked_mut(slice) })
1930 unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
1931 let ptr = slice.as_ptr();
1932 super::from_utf8_unchecked(slice::from_raw_parts(ptr, self.end))
1935 unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
1936 let ptr = slice.as_ptr();
1937 super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end))
1940 fn index(self, slice: &str) -> &Self::Output {
1942 self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, 0, end))
1945 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
1946 // is_char_boundary checks that the index is in [0, .len()]
1947 if slice.is_char_boundary(self.end) {
1948 unsafe { self.get_unchecked_mut(slice) }
1950 super::slice_error_fail(slice, 0, self.end)
1955 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
1956 impl SliceIndex<str> for ops::RangeFrom<usize> {
1959 fn get(self, slice: &str) -> Option<&Self::Output> {
1960 if slice.is_char_boundary(self.start) {
1961 Some(unsafe { self.get_unchecked(slice) })
1967 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
1968 if slice.is_char_boundary(self.start) {
1969 Some(unsafe { self.get_unchecked_mut(slice) })
1975 unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
1976 let ptr = slice.as_ptr().offset(self.start as isize);
1977 let len = slice.len() - self.start;
1978 super::from_utf8_unchecked(slice::from_raw_parts(ptr, len))
1981 unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
1982 let ptr = slice.as_ptr().offset(self.start as isize);
1983 let len = slice.len() - self.start;
1984 super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
1987 fn index(self, slice: &str) -> &Self::Output {
1988 let (start, end) = (self.start, slice.len());
1989 self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, start, end))
1992 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
1993 // is_char_boundary checks that the index is in [0, .len()]
1994 if slice.is_char_boundary(self.start) {
1995 unsafe { self.get_unchecked_mut(slice) }
1997 super::slice_error_fail(slice, self.start, slice.len())
2002 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
2003 impl SliceIndex<str> for ops::RangeInclusive<usize> {
2006 fn get(self, slice: &str) -> Option<&Self::Output> {
2007 if let Some(end) = self.end.checked_add(1) {
2008 (self.start..end).get(slice)
2014 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
2015 if let Some(end) = self.end.checked_add(1) {
2016 (self.start..end).get_mut(slice)
2022 unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
2023 (self.start..self.end+1).get_unchecked(slice)
2026 unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
2027 (self.start..self.end+1).get_unchecked_mut(slice)
2030 fn index(self, slice: &str) -> &Self::Output {
2031 assert!(self.end != usize::max_value(),
2032 "attempted to index str up to maximum usize");
2033 (self.start..self.end+1).index(slice)
2036 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
2037 assert!(self.end != usize::max_value(),
2038 "attempted to index str up to maximum usize");
2039 (self.start..self.end+1).index_mut(slice)
2045 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
2046 impl SliceIndex<str> for ops::RangeToInclusive<usize> {
2049 fn get(self, slice: &str) -> Option<&Self::Output> {
2050 if self.end < usize::max_value() && slice.is_char_boundary(self.end + 1) {
2051 Some(unsafe { self.get_unchecked(slice) })
2057 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
2058 if self.end < usize::max_value() && slice.is_char_boundary(self.end + 1) {
2059 Some(unsafe { self.get_unchecked_mut(slice) })
2065 unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
2066 let ptr = slice.as_ptr();
2067 super::from_utf8_unchecked(slice::from_raw_parts(ptr, self.end + 1))
2070 unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
2071 let ptr = slice.as_ptr();
2072 super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end + 1))
2075 fn index(self, slice: &str) -> &Self::Output {
2076 assert!(self.end != usize::max_value(),
2077 "attempted to index str up to maximum usize");
2078 let end = self.end + 1;
2079 self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, 0, end))
2082 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
2083 assert!(self.end != usize::max_value(),
2084 "attempted to index str up to maximum usize");
2085 if slice.is_char_boundary(self.end) {
2086 unsafe { self.get_unchecked_mut(slice) }
2088 super::slice_error_fail(slice, 0, self.end + 1)
2096 /// Methods for string slices
2097 #[allow(missing_docs)]
2099 #[unstable(feature = "core_str_ext",
2100 reason = "stable interface provided by `impl str` in later crates",
2103 // NB there are no docs here are they're all located on the StrExt trait in
2104 // liballoc, not here.
2106 #[stable(feature = "core", since = "1.6.0")]
2107 fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
2108 #[stable(feature = "core", since = "1.6.0")]
2109 fn chars(&self) -> Chars;
2110 #[stable(feature = "core", since = "1.6.0")]
2111 fn bytes(&self) -> Bytes;
2112 #[stable(feature = "core", since = "1.6.0")]
2113 fn char_indices(&self) -> CharIndices;
2114 #[stable(feature = "core", since = "1.6.0")]
2115 fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P>;
2116 #[stable(feature = "core", since = "1.6.0")]
2117 fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
2118 where P::Searcher: ReverseSearcher<'a>;
2119 #[stable(feature = "core", since = "1.6.0")]
2120 fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P>;
2121 #[stable(feature = "core", since = "1.6.0")]
2122 fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
2123 where P::Searcher: ReverseSearcher<'a>;
2124 #[stable(feature = "core", since = "1.6.0")]
2125 fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
2126 #[stable(feature = "core", since = "1.6.0")]
2127 fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
2128 where P::Searcher: ReverseSearcher<'a>;
2129 #[stable(feature = "core", since = "1.6.0")]
2130 fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P>;
2131 #[stable(feature = "core", since = "1.6.0")]
2132 fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
2133 where P::Searcher: ReverseSearcher<'a>;
2134 #[stable(feature = "core", since = "1.6.0")]
2135 fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
2136 #[stable(feature = "core", since = "1.6.0")]
2137 fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
2138 where P::Searcher: ReverseSearcher<'a>;
2139 #[stable(feature = "core", since = "1.6.0")]
2140 fn lines(&self) -> Lines;
2141 #[stable(feature = "core", since = "1.6.0")]
2142 #[rustc_deprecated(since = "1.6.0", reason = "use lines() instead now")]
2143 #[allow(deprecated)]
2144 fn lines_any(&self) -> LinesAny;
2145 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
2146 fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output>;
2147 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
2148 fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output>;
2149 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
2150 unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output;
2151 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
2152 unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output;
2153 #[stable(feature = "core", since = "1.6.0")]
2154 unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str;
2155 #[stable(feature = "core", since = "1.6.0")]
2156 unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str;
2157 #[stable(feature = "core", since = "1.6.0")]
2158 fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
2159 #[stable(feature = "core", since = "1.6.0")]
2160 fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
2161 where P::Searcher: ReverseSearcher<'a>;
2162 #[stable(feature = "core", since = "1.6.0")]
2163 fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
2164 where P::Searcher: DoubleEndedSearcher<'a>;
2165 #[stable(feature = "core", since = "1.6.0")]
2166 fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str;
2167 #[stable(feature = "core", since = "1.6.0")]
2168 fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
2169 where P::Searcher: ReverseSearcher<'a>;
2170 #[stable(feature = "is_char_boundary", since = "1.9.0")]
2171 fn is_char_boundary(&self, index: usize) -> bool;
2172 #[stable(feature = "core", since = "1.6.0")]
2173 fn as_bytes(&self) -> &[u8];
2174 #[stable(feature = "str_mut_extras", since = "1.20.0")]
2175 unsafe fn as_bytes_mut(&mut self) -> &mut [u8];
2176 #[stable(feature = "core", since = "1.6.0")]
2177 fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
2178 #[stable(feature = "core", since = "1.6.0")]
2179 fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
2180 where P::Searcher: ReverseSearcher<'a>;
2181 fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
2182 #[stable(feature = "core", since = "1.6.0")]
2183 fn split_at(&self, mid: usize) -> (&str, &str);
2184 #[stable(feature = "core", since = "1.6.0")]
2185 fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str);
2186 #[stable(feature = "core", since = "1.6.0")]
2187 fn as_ptr(&self) -> *const u8;
2188 #[stable(feature = "core", since = "1.6.0")]
2189 fn len(&self) -> usize;
2190 #[stable(feature = "core", since = "1.6.0")]
2191 fn is_empty(&self) -> bool;
2192 #[stable(feature = "core", since = "1.6.0")]
2193 fn parse<'a, T: TryFrom<&'a str>>(&'a self) -> Result<T, T::Error>;
2196 // truncate `&str` to length at most equal to `max`
2197 // return `true` if it were truncated, and the new str.
2198 fn truncate_to_char_boundary(s: &str, mut max: usize) -> (bool, &str) {
2202 while !s.is_char_boundary(max) {
2211 fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
2212 const MAX_DISPLAY_LENGTH: usize = 256;
2213 let (truncated, s_trunc) = truncate_to_char_boundary(s, MAX_DISPLAY_LENGTH);
2214 let ellipsis = if truncated { "[...]" } else { "" };
2217 if begin > s.len() || end > s.len() {
2218 let oob_index = if begin > s.len() { begin } else { end };
2219 panic!("byte index {} is out of bounds of `{}`{}", oob_index, s_trunc, ellipsis);
2223 assert!(begin <= end, "begin <= end ({} <= {}) when slicing `{}`{}",
2224 begin, end, s_trunc, ellipsis);
2226 // 3. character boundary
2227 let index = if !s.is_char_boundary(begin) { begin } else { end };
2228 // find the character
2229 let mut char_start = index;
2230 while !s.is_char_boundary(char_start) {
2233 // `char_start` must be less than len and a char boundary
2234 let ch = s[char_start..].chars().next().unwrap();
2235 let char_range = char_start .. char_start + ch.len_utf8();
2236 panic!("byte index {} is not a char boundary; it is inside {:?} (bytes {:?}) of `{}`{}",
2237 index, ch, char_range, s_trunc, ellipsis);
2240 #[stable(feature = "core", since = "1.6.0")]
2241 impl StrExt for str {
2243 fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
2244 pat.is_contained_in(self)
2248 fn chars(&self) -> Chars {
2249 Chars{iter: self.as_bytes().iter()}
2253 fn bytes(&self) -> Bytes {
2254 Bytes(self.as_bytes().iter().cloned())
2258 fn char_indices(&self) -> CharIndices {
2259 CharIndices { front_offset: 0, iter: self.chars() }
2263 fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
2264 Split(SplitInternal {
2267 matcher: pat.into_searcher(self),
2268 allow_trailing_empty: true,
2274 fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
2275 where P::Searcher: ReverseSearcher<'a>
2277 RSplit(self.split(pat).0)
2281 fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> {
2282 SplitN(SplitNInternal {
2283 iter: self.split(pat).0,
2289 fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
2290 where P::Searcher: ReverseSearcher<'a>
2292 RSplitN(self.splitn(count, pat).0)
2296 fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
2297 SplitTerminator(SplitInternal {
2298 allow_trailing_empty: false,
2304 fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
2305 where P::Searcher: ReverseSearcher<'a>
2307 RSplitTerminator(self.split_terminator(pat).0)
2311 fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
2312 Matches(MatchesInternal(pat.into_searcher(self)))
2316 fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
2317 where P::Searcher: ReverseSearcher<'a>
2319 RMatches(self.matches(pat).0)
2323 fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
2324 MatchIndices(MatchIndicesInternal(pat.into_searcher(self)))
2328 fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
2329 where P::Searcher: ReverseSearcher<'a>
2331 RMatchIndices(self.match_indices(pat).0)
2334 fn lines(&self) -> Lines {
2335 Lines(self.split_terminator('\n').map(LinesAnyMap))
2339 #[allow(deprecated)]
2340 fn lines_any(&self) -> LinesAny {
2341 LinesAny(self.lines())
2345 fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
2350 fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
2355 unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
2356 i.get_unchecked(self)
2360 unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
2361 i.get_unchecked_mut(self)
2365 unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
2366 (begin..end).get_unchecked(self)
2370 unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
2371 (begin..end).get_unchecked_mut(self)
2375 fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
2376 pat.is_prefix_of(self)
2380 fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
2381 where P::Searcher: ReverseSearcher<'a>
2383 pat.is_suffix_of(self)
2387 fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
2388 where P::Searcher: DoubleEndedSearcher<'a>
2392 let mut matcher = pat.into_searcher(self);
2393 if let Some((a, b)) = matcher.next_reject() {
2395 j = b; // Remember earliest known match, correct it below if
2396 // last match is different
2398 if let Some((_, b)) = matcher.next_reject_back() {
2402 // Searcher is known to return valid indices
2403 self.slice_unchecked(i, j)
2408 fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
2409 let mut i = self.len();
2410 let mut matcher = pat.into_searcher(self);
2411 if let Some((a, _)) = matcher.next_reject() {
2415 // Searcher is known to return valid indices
2416 self.slice_unchecked(i, self.len())
2421 fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
2422 where P::Searcher: ReverseSearcher<'a>
2425 let mut matcher = pat.into_searcher(self);
2426 if let Some((_, b)) = matcher.next_reject_back() {
2430 // Searcher is known to return valid indices
2431 self.slice_unchecked(0, j)
2436 fn is_char_boundary(&self, index: usize) -> bool {
2437 // 0 and len are always ok.
2438 // Test for 0 explicitly so that it can optimize out the check
2439 // easily and skip reading string data for that case.
2440 if index == 0 || index == self.len() { return true; }
2441 match self.as_bytes().get(index) {
2443 // This is bit magic equivalent to: b < 128 || b >= 192
2444 Some(&b) => (b as i8) >= -0x40,
2449 fn as_bytes(&self) -> &[u8] {
2450 unsafe { mem::transmute(self) }
2454 unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
2455 mem::transmute(self)
2458 fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
2459 pat.into_searcher(self).next_match().map(|(i, _)| i)
2462 fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
2463 where P::Searcher: ReverseSearcher<'a>
2465 pat.into_searcher(self).next_match_back().map(|(i, _)| i)
2468 fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
2473 fn split_at(&self, mid: usize) -> (&str, &str) {
2474 // is_char_boundary checks that the index is in [0, .len()]
2475 if self.is_char_boundary(mid) {
2477 (self.slice_unchecked(0, mid),
2478 self.slice_unchecked(mid, self.len()))
2481 slice_error_fail(self, 0, mid)
2485 fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
2486 // is_char_boundary checks that the index is in [0, .len()]
2487 if self.is_char_boundary(mid) {
2488 let len = self.len();
2489 let ptr = self.as_ptr() as *mut u8;
2491 (from_raw_parts_mut(ptr, mid),
2492 from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
2495 slice_error_fail(self, 0, mid)
2500 fn as_ptr(&self) -> *const u8 {
2501 self as *const str as *const u8
2505 fn len(&self) -> usize {
2506 self.as_bytes().len()
2510 fn is_empty(&self) -> bool { self.len() == 0 }
2513 fn parse<'a, T>(&'a self) -> Result<T, T::Error> where T: TryFrom<&'a str> {
2518 #[stable(feature = "rust1", since = "1.0.0")]
2519 impl AsRef<[u8]> for str {
2521 fn as_ref(&self) -> &[u8] {
2526 #[stable(feature = "rust1", since = "1.0.0")]
2527 impl<'a> Default for &'a str {
2528 /// Creates an empty str
2529 fn default() -> &'a str { "" }