]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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. | |
4 | // | |
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. | |
1a4d82fc | 10 | |
c1a9b12d | 11 | //! Unicode string slices |
1a4d82fc | 12 | //! |
c1a9b12d SL |
13 | //! *[See also the `str` primitive type](../primitive.str.html).* |
14 | ||
1a4d82fc | 15 | |
85aaf69f | 16 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 17 | |
62682a34 SL |
18 | // Many of the usings in this module are only used in the test configuration. |
19 | // It's cleaner to just turn off the unused_imports warning than to fix them. | |
20 | #![allow(unused_imports)] | |
21 | ||
1a4d82fc | 22 | use core::clone::Clone; |
c34b1796 | 23 | use core::iter::{Iterator, Extend}; |
1a4d82fc | 24 | use core::option::Option::{self, Some, None}; |
85aaf69f | 25 | use core::result::Result; |
1a4d82fc | 26 | use core::str as core_str; |
9346a6ac AL |
27 | use core::str::pattern::Pattern; |
28 | use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; | |
c1a9b12d | 29 | use core::mem; |
d9579d0f | 30 | use rustc_unicode::str::{UnicodeStr, Utf16Encoder}; |
1a4d82fc | 31 | |
85aaf69f SL |
32 | use vec_deque::VecDeque; |
33 | use borrow::{Borrow, ToOwned}; | |
1a4d82fc | 34 | use string::String; |
d9579d0f | 35 | use rustc_unicode; |
1a4d82fc JJ |
36 | use vec::Vec; |
37 | use slice::SliceConcatExt; | |
c1a9b12d | 38 | use boxed::Box; |
1a4d82fc | 39 | |
92a42be0 | 40 | #[stable(feature = "rust1", since = "1.0.0")] |
9346a6ac | 41 | pub use core::str::{FromStr, Utf8Error}; |
b039eaaf | 42 | #[allow(deprecated)] |
92a42be0 | 43 | #[stable(feature = "rust1", since = "1.0.0")] |
9346a6ac | 44 | pub use core::str::{Lines, LinesAny, CharRange}; |
92a42be0 | 45 | #[stable(feature = "rust1", since = "1.0.0")] |
9346a6ac | 46 | pub use core::str::{Split, RSplit}; |
92a42be0 | 47 | #[stable(feature = "rust1", since = "1.0.0")] |
9346a6ac | 48 | pub use core::str::{SplitN, RSplitN}; |
92a42be0 | 49 | #[stable(feature = "rust1", since = "1.0.0")] |
9346a6ac | 50 | pub use core::str::{SplitTerminator, RSplitTerminator}; |
92a42be0 | 51 | #[stable(feature = "rust1", since = "1.0.0")] |
9346a6ac | 52 | pub use core::str::{Matches, RMatches}; |
92a42be0 | 53 | #[stable(feature = "rust1", since = "1.0.0")] |
9346a6ac | 54 | pub use core::str::{MatchIndices, RMatchIndices}; |
92a42be0 | 55 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 56 | pub use core::str::{from_utf8, Chars, CharIndices, Bytes}; |
92a42be0 | 57 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 58 | pub use core::str::{from_utf8_unchecked, ParseBoolError}; |
92a42be0 SL |
59 | #[stable(feature = "rust1", since = "1.0.0")] |
60 | pub use rustc_unicode::str::SplitWhitespace; | |
61 | #[stable(feature = "rust1", since = "1.0.0")] | |
9346a6ac | 62 | pub use core::str::pattern; |
1a4d82fc | 63 | |
92a42be0 SL |
64 | #[unstable(feature = "slice_concat_ext", |
65 | reason = "trait should not have to exist", | |
66 | issue = "27747")] | |
d9579d0f AL |
67 | impl<S: Borrow<str>> SliceConcatExt<str> for [S] { |
68 | type Output = String; | |
69 | ||
1a4d82fc | 70 | fn concat(&self) -> String { |
c34b1796 | 71 | if self.is_empty() { |
1a4d82fc JJ |
72 | return String::new(); |
73 | } | |
74 | ||
75 | // `len` calculation may overflow but push_str will check boundaries | |
bd371182 | 76 | let len = self.iter().map(|s| s.borrow().len()).sum(); |
1a4d82fc JJ |
77 | let mut result = String::with_capacity(len); |
78 | ||
c34b1796 | 79 | for s in self { |
bd371182 | 80 | result.push_str(s.borrow()) |
1a4d82fc JJ |
81 | } |
82 | ||
83 | result | |
84 | } | |
85 | ||
c1a9b12d | 86 | fn join(&self, sep: &str) -> String { |
c34b1796 | 87 | if self.is_empty() { |
1a4d82fc JJ |
88 | return String::new(); |
89 | } | |
90 | ||
91 | // concat is faster | |
92 | if sep.is_empty() { | |
c34b1796 | 93 | return self.concat(); |
1a4d82fc JJ |
94 | } |
95 | ||
96 | // this is wrong without the guarantee that `self` is non-empty | |
97 | // `len` calculation may overflow but push_str but will check boundaries | |
92a42be0 SL |
98 | let len = sep.len() * (self.len() - 1) + |
99 | self.iter().map(|s| s.borrow().len()).sum::<usize>(); | |
1a4d82fc JJ |
100 | let mut result = String::with_capacity(len); |
101 | let mut first = true; | |
102 | ||
c34b1796 | 103 | for s in self { |
1a4d82fc JJ |
104 | if first { |
105 | first = false; | |
106 | } else { | |
107 | result.push_str(sep); | |
108 | } | |
bd371182 | 109 | result.push_str(s.borrow()); |
1a4d82fc JJ |
110 | } |
111 | result | |
112 | } | |
1a4d82fc | 113 | |
c1a9b12d SL |
114 | fn connect(&self, sep: &str) -> String { |
115 | self.join(sep) | |
116 | } | |
117 | } | |
1a4d82fc | 118 | |
b039eaaf | 119 | /// External iterator for a string's UTF-16 code units. |
c34b1796 AL |
120 | /// |
121 | /// For use with the `std::iter` module. | |
1a4d82fc | 122 | #[derive(Clone)] |
e9174d1e | 123 | #[unstable(feature = "str_utf16", issue = "27714")] |
1a4d82fc | 124 | pub struct Utf16Units<'a> { |
92a42be0 | 125 | encoder: Utf16Encoder<Chars<'a>>, |
1a4d82fc JJ |
126 | } |
127 | ||
85aaf69f | 128 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
129 | impl<'a> Iterator for Utf16Units<'a> { |
130 | type Item = u16; | |
131 | ||
132 | #[inline] | |
92a42be0 SL |
133 | fn next(&mut self) -> Option<u16> { |
134 | self.encoder.next() | |
135 | } | |
1a4d82fc JJ |
136 | |
137 | #[inline] | |
92a42be0 SL |
138 | fn size_hint(&self) -> (usize, Option<usize>) { |
139 | self.encoder.size_hint() | |
140 | } | |
1a4d82fc JJ |
141 | } |
142 | ||
1a4d82fc JJ |
143 | // Return the initial codepoint accumulator for the first byte. |
144 | // The first byte is special, only want bottom 5 bits for width 2, 4 bits | |
145 | // for width 3, and 3 bits for width 4 | |
146 | macro_rules! utf8_first_byte { | |
147 | ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32) | |
148 | } | |
149 | ||
150 | // return the value of $ch updated with continuation byte $byte | |
151 | macro_rules! utf8_acc_cont_byte { | |
c34b1796 | 152 | ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63) as u32) |
1a4d82fc JJ |
153 | } |
154 | ||
85aaf69f SL |
155 | #[stable(feature = "rust1", since = "1.0.0")] |
156 | impl Borrow<str> for String { | |
d9579d0f | 157 | #[inline] |
92a42be0 SL |
158 | fn borrow(&self) -> &str { |
159 | &self[..] | |
160 | } | |
1a4d82fc JJ |
161 | } |
162 | ||
85aaf69f SL |
163 | #[stable(feature = "rust1", since = "1.0.0")] |
164 | impl ToOwned for str { | |
165 | type Owned = String; | |
1a4d82fc | 166 | fn to_owned(&self) -> String { |
92a42be0 | 167 | unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) } |
1a4d82fc JJ |
168 | } |
169 | } | |
170 | ||
92a42be0 | 171 | /// Methods for string slices. |
c34b1796 AL |
172 | #[lang = "str"] |
173 | #[cfg(not(test))] | |
c34b1796 | 174 | impl str { |
92a42be0 SL |
175 | /// Returns the length of `self`. |
176 | /// | |
177 | /// This length is in bytes, not [`char`]s or graphemes. In other words, | |
178 | /// it may not be what a human considers the length of the string. | |
179 | /// | |
180 | /// [`char`]: primitive.char.html | |
1a4d82fc JJ |
181 | /// |
182 | /// # Examples | |
183 | /// | |
92a42be0 SL |
184 | /// Basic usage: |
185 | /// | |
c34b1796 | 186 | /// ``` |
92a42be0 SL |
187 | /// let len = "foo".len(); |
188 | /// assert_eq!(3, len); | |
189 | /// | |
190 | /// let len = "ƒoo".len(); // fancy f! | |
191 | /// assert_eq!(4, len); | |
1a4d82fc | 192 | /// ``` |
85aaf69f | 193 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 194 | #[inline] |
62682a34 SL |
195 | pub fn len(&self) -> usize { |
196 | core_str::StrExt::len(self) | |
1a4d82fc JJ |
197 | } |
198 | ||
62682a34 SL |
199 | /// Returns true if this slice has a length of zero bytes. |
200 | /// | |
201 | /// # Examples | |
202 | /// | |
92a42be0 SL |
203 | /// Basic usage: |
204 | /// | |
62682a34 | 205 | /// ``` |
92a42be0 SL |
206 | /// let s = ""; |
207 | /// assert!(s.is_empty()); | |
208 | /// | |
209 | /// let s = "not empty"; | |
210 | /// assert!(!s.is_empty()); | |
62682a34 | 211 | /// ``` |
1a4d82fc | 212 | #[inline] |
62682a34 SL |
213 | #[stable(feature = "rust1", since = "1.0.0")] |
214 | pub fn is_empty(&self) -> bool { | |
215 | core_str::StrExt::is_empty(self) | |
1a4d82fc JJ |
216 | } |
217 | ||
62682a34 SL |
218 | /// Checks that `index`-th byte lies at the start and/or end of a |
219 | /// UTF-8 code point sequence. | |
220 | /// | |
221 | /// The start and end of the string (when `index == self.len()`) are | |
222 | /// considered to be | |
223 | /// boundaries. | |
224 | /// | |
c1a9b12d | 225 | /// Returns `false` if `index` is greater than `self.len()`. |
1a4d82fc | 226 | /// |
c34b1796 | 227 | /// # Examples |
1a4d82fc | 228 | /// |
c34b1796 | 229 | /// ``` |
c1a9b12d SL |
230 | /// #![feature(str_char)] |
231 | /// | |
62682a34 SL |
232 | /// let s = "Löwe 老虎 Léopard"; |
233 | /// assert!(s.is_char_boundary(0)); | |
234 | /// // start of `老` | |
235 | /// assert!(s.is_char_boundary(6)); | |
236 | /// assert!(s.is_char_boundary(s.len())); | |
c34b1796 | 237 | /// |
62682a34 SL |
238 | /// // second byte of `ö` |
239 | /// assert!(!s.is_char_boundary(2)); | |
240 | /// | |
241 | /// // third byte of `老` | |
242 | /// assert!(!s.is_char_boundary(8)); | |
1a4d82fc | 243 | /// ``` |
62682a34 SL |
244 | #[unstable(feature = "str_char", |
245 | reason = "it is unclear whether this method pulls its weight \ | |
246 | with the existence of the char_indices iterator or \ | |
247 | this method may want to be replaced with checked \ | |
e9174d1e SL |
248 | slicing", |
249 | issue = "27754")] | |
c1a9b12d | 250 | #[inline] |
62682a34 SL |
251 | pub fn is_char_boundary(&self, index: usize) -> bool { |
252 | core_str::StrExt::is_char_boundary(self, index) | |
1a4d82fc JJ |
253 | } |
254 | ||
92a42be0 | 255 | /// Converts a string slice to a byte slice. |
1a4d82fc | 256 | /// |
c34b1796 | 257 | /// # Examples |
1a4d82fc | 258 | /// |
92a42be0 SL |
259 | /// Basic usage: |
260 | /// | |
1a4d82fc | 261 | /// ``` |
92a42be0 SL |
262 | /// let bytes = "bors".as_bytes(); |
263 | /// assert_eq!(b"bors", bytes); | |
1a4d82fc | 264 | /// ``` |
85aaf69f | 265 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
266 | #[inline(always)] |
267 | pub fn as_bytes(&self) -> &[u8] { | |
268 | core_str::StrExt::as_bytes(self) | |
1a4d82fc JJ |
269 | } |
270 | ||
92a42be0 | 271 | /// Converts a string slice to a raw pointer. |
62682a34 | 272 | /// |
92a42be0 SL |
273 | /// As string slices are a slice of bytes, the raw pointer points to a |
274 | /// `u8`. This pointer will be pointing to the first byte of the string | |
275 | /// slice. | |
1a4d82fc | 276 | /// |
c34b1796 | 277 | /// # Examples |
1a4d82fc | 278 | /// |
92a42be0 SL |
279 | /// Basic usage: |
280 | /// | |
c34b1796 | 281 | /// ``` |
62682a34 | 282 | /// let s = "Hello"; |
92a42be0 | 283 | /// let ptr = s.as_ptr(); |
1a4d82fc | 284 | /// ``` |
85aaf69f | 285 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
286 | #[inline] |
287 | pub fn as_ptr(&self) -> *const u8 { | |
288 | core_str::StrExt::as_ptr(self) | |
1a4d82fc JJ |
289 | } |
290 | ||
92a42be0 SL |
291 | /// Creates a string slice from another string slice, bypassing safety |
292 | /// checks. | |
62682a34 | 293 | /// |
92a42be0 SL |
294 | /// This new slice goes from `begin` to `end`, including `begin` but |
295 | /// excluding `end`. | |
296 | /// | |
297 | /// To get a mutable string slice instead, see the | |
298 | /// [`slice_mut_unchecked()`] method. | |
299 | /// | |
300 | /// [`slice_mut_unchecked()`]: #method.slice_mut_unchecked | |
62682a34 | 301 | /// |
b039eaaf | 302 | /// # Safety |
62682a34 | 303 | /// |
92a42be0 SL |
304 | /// Callers of this function are responsible that three preconditions are |
305 | /// satisifed: | |
306 | /// | |
307 | /// * `begin` must come before `end`. | |
308 | /// * `begin` and `end` must be bye positions within the string slice. | |
309 | /// * `begin` and `end` must lie on UTF-8 sequence boundaries. | |
c34b1796 AL |
310 | /// |
311 | /// # Examples | |
312 | /// | |
92a42be0 SL |
313 | /// Basic usage: |
314 | /// | |
c34b1796 | 315 | /// ``` |
62682a34 | 316 | /// let s = "Löwe 老虎 Léopard"; |
c34b1796 | 317 | /// |
62682a34 | 318 | /// unsafe { |
92a42be0 SL |
319 | /// assert_eq!("Löwe 老虎 Léopard", s.slice_unchecked(0, 21)); |
320 | /// } | |
321 | /// | |
322 | /// let s = "Hello, world!"; | |
323 | /// | |
324 | /// unsafe { | |
325 | /// assert_eq!("world", s.slice_unchecked(7, 12)); | |
62682a34 | 326 | /// } |
c34b1796 | 327 | /// ``` |
85aaf69f | 328 | #[stable(feature = "rust1", since = "1.0.0")] |
c1a9b12d | 329 | #[inline] |
62682a34 SL |
330 | pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str { |
331 | core_str::StrExt::slice_unchecked(self, begin, end) | |
1a4d82fc JJ |
332 | } |
333 | ||
92a42be0 SL |
334 | /// Creates a string slice from another string slice, bypassing safety |
335 | /// checks. | |
c1a9b12d | 336 | /// |
92a42be0 SL |
337 | /// This new slice goes from `begin` to `end`, including `begin` but |
338 | /// excluding `end`. | |
339 | /// | |
340 | /// To get an immutable string slice instead, see the | |
341 | /// [`slice_unchecked()`] method. | |
342 | /// | |
343 | /// [`slice_unchecked()`]: #method.slice_unchecked | |
344 | /// | |
345 | /// # Safety | |
346 | /// | |
347 | /// Callers of this function are responsible that three preconditions are | |
348 | /// satisifed: | |
349 | /// | |
350 | /// * `begin` must come before `end`. | |
351 | /// * `begin` and `end` must be bye positions within the string slice. | |
352 | /// * `begin` and `end` must lie on UTF-8 sequence boundaries. | |
b039eaaf | 353 | #[stable(feature = "str_slice_mut", since = "1.5.0")] |
c1a9b12d SL |
354 | #[inline] |
355 | pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str { | |
356 | core_str::StrExt::slice_mut_unchecked(self, begin, end) | |
357 | } | |
358 | ||
92a42be0 | 359 | /// Given a byte position, returns the next `char` and its index. |
9346a6ac | 360 | /// |
62682a34 | 361 | /// # Panics |
1a4d82fc | 362 | /// |
62682a34 | 363 | /// If `i` is greater than or equal to the length of the string. |
c1a9b12d | 364 | /// If `i` is not the index of the beginning of a valid UTF-8 sequence. |
c34b1796 | 365 | /// |
62682a34 | 366 | /// # Examples |
1a4d82fc | 367 | /// |
c1a9b12d | 368 | /// This example manually iterates through the code points of a string; |
62682a34 SL |
369 | /// this should normally be |
370 | /// done by `.chars()` or `.char_indices()`. | |
c34b1796 AL |
371 | /// |
372 | /// ``` | |
92a42be0 | 373 | /// #![feature(str_char)] |
c1a9b12d | 374 | /// |
62682a34 | 375 | /// use std::str::CharRange; |
9346a6ac | 376 | /// |
c1a9b12d | 377 | /// let s = "中华Việt Nam"; |
62682a34 SL |
378 | /// let mut i = 0; |
379 | /// while i < s.len() { | |
380 | /// let CharRange {ch, next} = s.char_range_at(i); | |
381 | /// println!("{}: {}", i, ch); | |
382 | /// i = next; | |
383 | /// } | |
384 | /// ``` | |
9346a6ac | 385 | /// |
62682a34 | 386 | /// This outputs: |
9346a6ac | 387 | /// |
62682a34 SL |
388 | /// ```text |
389 | /// 0: 中 | |
390 | /// 3: 华 | |
391 | /// 6: V | |
392 | /// 7: i | |
c1a9b12d | 393 | /// 8: e |
e9174d1e SL |
394 | /// 9: |
395 | /// 11: | |
c1a9b12d SL |
396 | /// 13: t |
397 | /// 14: | |
398 | /// 15: N | |
399 | /// 16: a | |
400 | /// 17: m | |
1a4d82fc | 401 | /// ``` |
62682a34 SL |
402 | #[unstable(feature = "str_char", |
403 | reason = "often replaced by char_indices, this method may \ | |
404 | be removed in favor of just char_at() or eventually \ | |
e9174d1e SL |
405 | removed altogether", |
406 | issue = "27754")] | |
c1a9b12d | 407 | #[inline] |
62682a34 SL |
408 | pub fn char_range_at(&self, start: usize) -> CharRange { |
409 | core_str::StrExt::char_range_at(self, start) | |
1a4d82fc JJ |
410 | } |
411 | ||
92a42be0 | 412 | /// Given a byte position, returns the previous `char` and its position. |
c1a9b12d SL |
413 | /// |
414 | /// Note that Unicode has many features, such as combining marks, ligatures, | |
415 | /// and direction marks, that need to be taken into account to correctly reverse a string. | |
9346a6ac | 416 | /// |
62682a34 | 417 | /// Returns 0 for next index if called on start index 0. |
9346a6ac | 418 | /// |
62682a34 | 419 | /// # Panics |
9346a6ac | 420 | /// |
62682a34 | 421 | /// If `i` is greater than the length of the string. |
c1a9b12d | 422 | /// If `i` is not an index following a valid UTF-8 sequence. |
1a4d82fc | 423 | /// |
c34b1796 AL |
424 | /// # Examples |
425 | /// | |
c1a9b12d | 426 | /// This example manually iterates through the code points of a string; |
62682a34 SL |
427 | /// this should normally be |
428 | /// done by `.chars().rev()` or `.char_indices()`. | |
c34b1796 AL |
429 | /// |
430 | /// ``` | |
92a42be0 | 431 | /// #![feature(str_char)] |
c1a9b12d | 432 | /// |
62682a34 | 433 | /// use std::str::CharRange; |
1a4d82fc | 434 | /// |
c1a9b12d | 435 | /// let s = "中华Việt Nam"; |
62682a34 SL |
436 | /// let mut i = s.len(); |
437 | /// while i > 0 { | |
438 | /// let CharRange {ch, next} = s.char_range_at_reverse(i); | |
439 | /// println!("{}: {}", i, ch); | |
440 | /// i = next; | |
441 | /// } | |
c34b1796 | 442 | /// ``` |
1a4d82fc | 443 | /// |
62682a34 | 444 | /// This outputs: |
1a4d82fc | 445 | /// |
62682a34 | 446 | /// ```text |
c1a9b12d SL |
447 | /// 18: m |
448 | /// 17: a | |
449 | /// 16: N | |
450 | /// 15: | |
451 | /// 14: t | |
e9174d1e SL |
452 | /// 13: |
453 | /// 11: | |
c1a9b12d | 454 | /// 9: e |
62682a34 SL |
455 | /// 8: i |
456 | /// 7: V | |
457 | /// 6: 华 | |
458 | /// 3: 中 | |
1a4d82fc | 459 | /// ``` |
62682a34 SL |
460 | #[unstable(feature = "str_char", |
461 | reason = "often replaced by char_indices, this method may \ | |
462 | be removed in favor of just char_at_reverse() or \ | |
e9174d1e SL |
463 | eventually removed altogether", |
464 | issue = "27754")] | |
c1a9b12d | 465 | #[inline] |
62682a34 SL |
466 | pub fn char_range_at_reverse(&self, start: usize) -> CharRange { |
467 | core_str::StrExt::char_range_at_reverse(self, start) | |
1a4d82fc JJ |
468 | } |
469 | ||
92a42be0 | 470 | /// Given a byte position, returns the `char` at that position. |
9346a6ac | 471 | /// |
62682a34 | 472 | /// # Panics |
9346a6ac | 473 | /// |
62682a34 | 474 | /// If `i` is greater than or equal to the length of the string. |
c1a9b12d | 475 | /// If `i` is not the index of the beginning of a valid UTF-8 sequence. |
1a4d82fc | 476 | /// |
c34b1796 | 477 | /// # Examples |
1a4d82fc | 478 | /// |
c34b1796 | 479 | /// ``` |
c1a9b12d SL |
480 | /// #![feature(str_char)] |
481 | /// | |
62682a34 SL |
482 | /// let s = "abπc"; |
483 | /// assert_eq!(s.char_at(1), 'b'); | |
484 | /// assert_eq!(s.char_at(2), 'π'); | |
c1a9b12d | 485 | /// assert_eq!(s.char_at(4), 'c'); |
c34b1796 | 486 | /// ``` |
62682a34 SL |
487 | #[unstable(feature = "str_char", |
488 | reason = "frequently replaced by the chars() iterator, this \ | |
489 | method may be removed or possibly renamed in the \ | |
490 | future; it is normally replaced by chars/char_indices \ | |
491 | iterators or by getting the first char from a \ | |
e9174d1e SL |
492 | subslice", |
493 | issue = "27754")] | |
c1a9b12d | 494 | #[inline] |
62682a34 SL |
495 | pub fn char_at(&self, i: usize) -> char { |
496 | core_str::StrExt::char_at(self, i) | |
9346a6ac AL |
497 | } |
498 | ||
92a42be0 | 499 | /// Given a byte position, returns the `char` at that position, counting |
62682a34 | 500 | /// from the end. |
9346a6ac | 501 | /// |
62682a34 | 502 | /// # Panics |
9346a6ac | 503 | /// |
62682a34 | 504 | /// If `i` is greater than the length of the string. |
c1a9b12d | 505 | /// If `i` is not an index following a valid UTF-8 sequence. |
9346a6ac AL |
506 | /// |
507 | /// # Examples | |
508 | /// | |
9346a6ac | 509 | /// ``` |
c1a9b12d SL |
510 | /// #![feature(str_char)] |
511 | /// | |
62682a34 SL |
512 | /// let s = "abπc"; |
513 | /// assert_eq!(s.char_at_reverse(1), 'a'); | |
514 | /// assert_eq!(s.char_at_reverse(2), 'b'); | |
c1a9b12d | 515 | /// assert_eq!(s.char_at_reverse(3), 'π'); |
9346a6ac | 516 | /// ``` |
62682a34 SL |
517 | #[unstable(feature = "str_char", |
518 | reason = "see char_at for more details, but reverse semantics \ | |
519 | are also somewhat unclear, especially with which \ | |
e9174d1e SL |
520 | cases generate panics", |
521 | issue = "27754")] | |
c1a9b12d | 522 | #[inline] |
62682a34 SL |
523 | pub fn char_at_reverse(&self, i: usize) -> char { |
524 | core_str::StrExt::char_at_reverse(self, i) | |
c34b1796 AL |
525 | } |
526 | ||
92a42be0 | 527 | /// Retrieves the first `char` from a `&str` and returns it. |
c1a9b12d SL |
528 | /// |
529 | /// Note that a single Unicode character (grapheme cluster) | |
530 | /// can be composed of multiple `char`s. | |
9346a6ac | 531 | /// |
62682a34 | 532 | /// This does not allocate a new string; instead, it returns a slice that |
c1a9b12d | 533 | /// points one code point beyond the code point that was shifted. |
9346a6ac | 534 | /// |
c1a9b12d | 535 | /// `None` is returned if the slice is empty. |
9346a6ac | 536 | /// |
c34b1796 AL |
537 | /// # Examples |
538 | /// | |
c34b1796 | 539 | /// ``` |
c1a9b12d SL |
540 | /// #![feature(str_char)] |
541 | /// | |
542 | /// let s = "Łódź"; // \u{141}o\u{301}dz\u{301} | |
62682a34 | 543 | /// let (c, s1) = s.slice_shift_char().unwrap(); |
9346a6ac | 544 | /// |
c1a9b12d SL |
545 | /// assert_eq!(c, 'Ł'); |
546 | /// assert_eq!(s1, "ódź"); | |
c34b1796 | 547 | /// |
62682a34 | 548 | /// let (c, s2) = s1.slice_shift_char().unwrap(); |
1a4d82fc | 549 | /// |
c1a9b12d SL |
550 | /// assert_eq!(c, 'o'); |
551 | /// assert_eq!(s2, "\u{301}dz\u{301}"); | |
c34b1796 | 552 | /// ``` |
62682a34 SL |
553 | #[unstable(feature = "str_char", |
554 | reason = "awaiting conventions about shifting and slices and \ | |
555 | may not be warranted with the existence of the chars \ | |
e9174d1e SL |
556 | and/or char_indices iterators", |
557 | issue = "27754")] | |
c1a9b12d | 558 | #[inline] |
62682a34 SL |
559 | pub fn slice_shift_char(&self) -> Option<(char, &str)> { |
560 | core_str::StrExt::slice_shift_char(self) | |
1a4d82fc JJ |
561 | } |
562 | ||
62682a34 | 563 | /// Divide one string slice into two at an index. |
9346a6ac | 564 | /// |
92a42be0 SL |
565 | /// The argument, `mid`, should be a byte offset from the start of the |
566 | /// string. It must also be on the boundary of a UTF-8 code point. | |
567 | /// | |
568 | /// The two slices returned go from the start of the string slice to `mid`, | |
569 | /// and from `mid` to the end of the string slice. | |
9346a6ac | 570 | /// |
92a42be0 SL |
571 | /// To get mutable string slices instead, see the [`split_at_mut()`] |
572 | /// method. | |
573 | /// | |
574 | /// [`split_at_mut()`]: #method.split_at_mut | |
9346a6ac | 575 | /// |
62682a34 | 576 | /// # Panics |
9346a6ac | 577 | /// |
92a42be0 SL |
578 | /// Panics if `mid` is not on a UTF-8 code point boundary, or if it is |
579 | /// beyond the last code point of the string slice. | |
9346a6ac AL |
580 | /// |
581 | /// # Examples | |
92a42be0 SL |
582 | /// |
583 | /// Basic usage: | |
584 | /// | |
9346a6ac | 585 | /// ``` |
92a42be0 | 586 | /// let s = "Per Martin-Löf"; |
9346a6ac | 587 | /// |
92a42be0 SL |
588 | /// let (first, last) = s.split_at(3); |
589 | /// | |
590 | /// assert_eq!("Per", first); | |
591 | /// assert_eq!(" Martin-Löf", last); | |
9346a6ac | 592 | /// ``` |
62682a34 | 593 | #[inline] |
e9174d1e | 594 | #[stable(feature = "str_split_at", since = "1.4.0")] |
62682a34 SL |
595 | pub fn split_at(&self, mid: usize) -> (&str, &str) { |
596 | core_str::StrExt::split_at(self, mid) | |
9346a6ac AL |
597 | } |
598 | ||
c1a9b12d | 599 | /// Divide one mutable string slice into two at an index. |
92a42be0 SL |
600 | /// |
601 | /// The argument, `mid`, should be a byte offset from the start of the | |
602 | /// string. It must also be on the boundary of a UTF-8 code point. | |
603 | /// | |
604 | /// The two slices returned go from the start of the string slice to `mid`, | |
605 | /// and from `mid` to the end of the string slice. | |
606 | /// | |
607 | /// To get immutable string slices instead, see the [`split_at()`] method. | |
608 | /// | |
609 | /// [`split_at()`]: #method.split_at | |
610 | /// | |
611 | /// # Panics | |
612 | /// | |
613 | /// Panics if `mid` is not on a UTF-8 code point boundary, or if it is | |
614 | /// beyond the last code point of the string slice. | |
615 | /// | |
616 | /// # Examples | |
617 | /// | |
618 | /// Basic usage: | |
619 | /// | |
620 | /// ``` | |
621 | /// let s = "Per Martin-Löf"; | |
622 | /// | |
623 | /// let (first, last) = s.split_at(3); | |
624 | /// | |
625 | /// assert_eq!("Per", first); | |
626 | /// assert_eq!(" Martin-Löf", last); | |
627 | /// ``` | |
c1a9b12d | 628 | #[inline] |
e9174d1e | 629 | #[stable(feature = "str_split_at", since = "1.4.0")] |
c1a9b12d SL |
630 | pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) { |
631 | core_str::StrExt::split_at_mut(self, mid) | |
632 | } | |
633 | ||
92a42be0 | 634 | /// Returns an iterator over the `char`s of a string slice. |
c1a9b12d | 635 | /// |
92a42be0 SL |
636 | /// As a string slice consists of valid UTF-8, we can iterate through a |
637 | /// string slice by [`char`]. This method returns such an iterator. | |
c1a9b12d | 638 | /// |
92a42be0 SL |
639 | /// It's important to remember that [`char`] represents a Unicode Scalar |
640 | /// Value, and may not match your idea of what a 'character' is. Iteration | |
641 | /// over grapheme clusters may be what you actually want. | |
c1a9b12d | 642 | /// |
92a42be0 | 643 | /// [`char`]: ../primitive.char.html |
9346a6ac AL |
644 | /// |
645 | /// # Examples | |
646 | /// | |
92a42be0 SL |
647 | /// Basic usage: |
648 | /// | |
9346a6ac | 649 | /// ``` |
92a42be0 SL |
650 | /// let word = "goodbye"; |
651 | /// | |
652 | /// let count = word.chars().count(); | |
653 | /// assert_eq!(7, count); | |
9346a6ac | 654 | /// |
92a42be0 SL |
655 | /// let mut chars = word.chars(); |
656 | /// | |
657 | /// assert_eq!(Some('g'), chars.next()); | |
658 | /// assert_eq!(Some('o'), chars.next()); | |
659 | /// assert_eq!(Some('o'), chars.next()); | |
660 | /// assert_eq!(Some('d'), chars.next()); | |
661 | /// assert_eq!(Some('b'), chars.next()); | |
662 | /// assert_eq!(Some('y'), chars.next()); | |
663 | /// assert_eq!(Some('e'), chars.next()); | |
664 | /// | |
665 | /// assert_eq!(None, chars.next()); | |
666 | /// ``` | |
667 | /// | |
668 | /// Remember, `char`s may not match your human intuition about characters: | |
669 | /// | |
670 | /// ``` | |
671 | /// let y = "y̆"; | |
672 | /// | |
673 | /// let mut chars = y.chars(); | |
674 | /// | |
675 | /// assert_eq!(Some('y'), chars.next()); // not 'y̆' | |
676 | /// assert_eq!(Some('\u{0306}'), chars.next()); | |
677 | /// | |
678 | /// assert_eq!(None, chars.next()); | |
9346a6ac | 679 | /// ``` |
62682a34 | 680 | #[stable(feature = "rust1", since = "1.0.0")] |
c1a9b12d | 681 | #[inline] |
62682a34 SL |
682 | pub fn chars(&self) -> Chars { |
683 | core_str::StrExt::chars(self) | |
9346a6ac | 684 | } |
92a42be0 SL |
685 | /// Returns an iterator over the `char`s of a string slice, and their |
686 | /// positions. | |
687 | /// | |
688 | /// As a string slice consists of valid UTF-8, we can iterate through a | |
689 | /// string slice by `char`. This method returns an iterator of both | |
690 | /// these `char`s, as well as their byte positions. | |
691 | /// | |
692 | /// The iterator yields tuples. The position is first, the `char` is | |
693 | /// second. | |
9346a6ac | 694 | /// |
c34b1796 | 695 | /// # Examples |
1a4d82fc | 696 | /// |
92a42be0 SL |
697 | /// Basic usage: |
698 | /// | |
c34b1796 | 699 | /// ``` |
92a42be0 | 700 | /// let word = "goodbye"; |
1a4d82fc | 701 | /// |
92a42be0 SL |
702 | /// let count = word.char_indices().count(); |
703 | /// assert_eq!(7, count); | |
704 | /// | |
705 | /// let mut char_indices = word.char_indices(); | |
706 | /// | |
707 | /// assert_eq!(Some((0, 'g')), char_indices.next()); | |
708 | /// assert_eq!(Some((1, 'o')), char_indices.next()); | |
709 | /// assert_eq!(Some((2, 'o')), char_indices.next()); | |
710 | /// assert_eq!(Some((3, 'd')), char_indices.next()); | |
711 | /// assert_eq!(Some((4, 'b')), char_indices.next()); | |
712 | /// assert_eq!(Some((5, 'y')), char_indices.next()); | |
713 | /// assert_eq!(Some((6, 'e')), char_indices.next()); | |
714 | /// | |
715 | /// assert_eq!(None, char_indices.next()); | |
716 | /// ``` | |
717 | /// | |
718 | /// Remember, `char`s may not match your human intuition about characters: | |
719 | /// | |
720 | /// ``` | |
721 | /// let y = "y̆"; | |
722 | /// | |
723 | /// let mut char_indices = y.char_indices(); | |
724 | /// | |
725 | /// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆') | |
726 | /// assert_eq!(Some((1, '\u{0306}')), char_indices.next()); | |
727 | /// | |
728 | /// assert_eq!(None, char_indices.next()); | |
1a4d82fc | 729 | /// ``` |
62682a34 | 730 | #[stable(feature = "rust1", since = "1.0.0")] |
c1a9b12d | 731 | #[inline] |
62682a34 SL |
732 | pub fn char_indices(&self) -> CharIndices { |
733 | core_str::StrExt::char_indices(self) | |
1a4d82fc JJ |
734 | } |
735 | ||
92a42be0 SL |
736 | /// An iterator over the bytes of a string slice. |
737 | /// | |
738 | /// As a string slice consists of a sequence of bytes, we can iterate | |
739 | /// through a string slice by byte. This method returns such an iterator. | |
9346a6ac | 740 | /// |
62682a34 | 741 | /// # Examples |
9346a6ac | 742 | /// |
92a42be0 SL |
743 | /// Basic usage: |
744 | /// | |
62682a34 | 745 | /// ``` |
92a42be0 | 746 | /// let mut bytes = "bors".bytes(); |
9346a6ac | 747 | /// |
92a42be0 SL |
748 | /// assert_eq!(Some(b'b'), bytes.next()); |
749 | /// assert_eq!(Some(b'o'), bytes.next()); | |
750 | /// assert_eq!(Some(b'r'), bytes.next()); | |
751 | /// assert_eq!(Some(b's'), bytes.next()); | |
752 | /// | |
753 | /// assert_eq!(None, bytes.next()); | |
62682a34 SL |
754 | /// ``` |
755 | #[stable(feature = "rust1", since = "1.0.0")] | |
c1a9b12d | 756 | #[inline] |
62682a34 SL |
757 | pub fn bytes(&self) -> Bytes { |
758 | core_str::StrExt::bytes(self) | |
759 | } | |
760 | ||
92a42be0 SL |
761 | /// Split a string slice by whitespace. |
762 | /// | |
763 | /// The iterator returned will return string slices that are sub-slices of | |
764 | /// the original string slice, separated by any amount of whitespace. | |
765 | /// | |
766 | /// 'Whitespace' is defined according to the terms of the Unicode Derived | |
767 | /// Core Property `White_Space`. | |
9346a6ac AL |
768 | /// |
769 | /// # Examples | |
770 | /// | |
92a42be0 SL |
771 | /// Basic usage: |
772 | /// | |
9346a6ac | 773 | /// ``` |
92a42be0 | 774 | /// let mut iter = "A few words".split_whitespace(); |
9346a6ac | 775 | /// |
92a42be0 SL |
776 | /// assert_eq!(Some("A"), iter.next()); |
777 | /// assert_eq!(Some("few"), iter.next()); | |
778 | /// assert_eq!(Some("words"), iter.next()); | |
779 | /// | |
780 | /// assert_eq!(None, iter.next()); | |
781 | /// ``` | |
782 | /// | |
783 | /// All kinds of whitespace are considered: | |
784 | /// | |
785 | /// ``` | |
786 | /// let mut iter = " Mary had\ta\u{2009}little \n\t lamb".split_whitespace(); | |
787 | /// assert_eq!(Some("Mary"), iter.next()); | |
788 | /// assert_eq!(Some("had"), iter.next()); | |
789 | /// assert_eq!(Some("a"), iter.next()); | |
790 | /// assert_eq!(Some("little"), iter.next()); | |
791 | /// assert_eq!(Some("lamb"), iter.next()); | |
792 | /// | |
793 | /// assert_eq!(None, iter.next()); | |
62682a34 SL |
794 | /// ``` |
795 | #[stable(feature = "split_whitespace", since = "1.1.0")] | |
c1a9b12d | 796 | #[inline] |
62682a34 SL |
797 | pub fn split_whitespace(&self) -> SplitWhitespace { |
798 | UnicodeStr::split_whitespace(self) | |
799 | } | |
800 | ||
92a42be0 SL |
801 | /// An iterator over the lines of a string, as string slices. |
802 | /// | |
803 | /// Lines are ended with either a newline (`\n`) or a carriage return with | |
804 | /// a line feed (`\r\n`). | |
1a4d82fc | 805 | /// |
92a42be0 | 806 | /// The final line ending is optional. |
1a4d82fc | 807 | /// |
c34b1796 | 808 | /// # Examples |
1a4d82fc | 809 | /// |
92a42be0 SL |
810 | /// Basic usage: |
811 | /// | |
1a4d82fc | 812 | /// ``` |
92a42be0 SL |
813 | /// let text = "foo\r\nbar\n\nbaz\n"; |
814 | /// let mut lines = text.lines(); | |
815 | /// | |
816 | /// assert_eq!(Some("foo"), lines.next()); | |
817 | /// assert_eq!(Some("bar"), lines.next()); | |
818 | /// assert_eq!(Some(""), lines.next()); | |
819 | /// assert_eq!(Some("baz"), lines.next()); | |
1a4d82fc | 820 | /// |
92a42be0 | 821 | /// assert_eq!(None, lines.next()); |
c34b1796 | 822 | /// ``` |
1a4d82fc | 823 | /// |
92a42be0 | 824 | /// The final line ending isn't required: |
c34b1796 AL |
825 | /// |
826 | /// ``` | |
92a42be0 SL |
827 | /// let text = "foo\nbar\n\r\nbaz"; |
828 | /// let mut lines = text.lines(); | |
c34b1796 | 829 | /// |
92a42be0 SL |
830 | /// assert_eq!(Some("foo"), lines.next()); |
831 | /// assert_eq!(Some("bar"), lines.next()); | |
832 | /// assert_eq!(Some(""), lines.next()); | |
833 | /// assert_eq!(Some("baz"), lines.next()); | |
834 | /// | |
835 | /// assert_eq!(None, lines.next()); | |
1a4d82fc | 836 | /// ``` |
85aaf69f | 837 | #[stable(feature = "rust1", since = "1.0.0")] |
c1a9b12d | 838 | #[inline] |
c34b1796 | 839 | pub fn lines(&self) -> Lines { |
62682a34 | 840 | core_str::StrExt::lines(self) |
1a4d82fc JJ |
841 | } |
842 | ||
92a42be0 | 843 | /// An iterator over the lines of a string. |
85aaf69f | 844 | #[stable(feature = "rust1", since = "1.0.0")] |
92a42be0 | 845 | #[rustc_deprecated(since = "1.4.0", reason = "use lines() instead now")] |
c1a9b12d | 846 | #[inline] |
e9174d1e | 847 | #[allow(deprecated)] |
c34b1796 | 848 | pub fn lines_any(&self) -> LinesAny { |
62682a34 | 849 | core_str::StrExt::lines_any(self) |
1a4d82fc | 850 | } |
62682a34 | 851 | |
62682a34 SL |
852 | /// Returns an iterator of `u16` over the string encoded as UTF-16. |
853 | #[unstable(feature = "str_utf16", | |
e9174d1e SL |
854 | reason = "this functionality may only be provided by libunicode", |
855 | issue = "27714")] | |
62682a34 SL |
856 | pub fn utf16_units(&self) -> Utf16Units { |
857 | Utf16Units { encoder: Utf16Encoder::new(self[..].chars()) } | |
858 | } | |
859 | ||
92a42be0 SL |
860 | /// Returns `true` if the given `&str` is a sub-slice of this string slice. |
861 | /// | |
862 | /// Returns `false` if it's not. | |
c34b1796 AL |
863 | /// |
864 | /// # Examples | |
865 | /// | |
92a42be0 SL |
866 | /// Basic usage: |
867 | /// | |
c34b1796 | 868 | /// ``` |
92a42be0 | 869 | /// let bananas = "bananas"; |
c34b1796 | 870 | /// |
92a42be0 SL |
871 | /// assert!(bananas.contains("nana")); |
872 | /// assert!(!bananas.contains("apples")); | |
c34b1796 | 873 | /// ``` |
85aaf69f | 874 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
875 | pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool { |
876 | core_str::StrExt::contains(self, pat) | |
1a4d82fc JJ |
877 | } |
878 | ||
92a42be0 SL |
879 | /// Returns `true` if the given `&str` is a prefix of this string slice. |
880 | /// | |
881 | /// Returns `false` if it's not. | |
1a4d82fc | 882 | /// |
c34b1796 | 883 | /// # Examples |
1a4d82fc | 884 | /// |
92a42be0 SL |
885 | /// Basic usage: |
886 | /// | |
c34b1796 | 887 | /// ``` |
92a42be0 SL |
888 | /// let bananas = "bananas"; |
889 | /// | |
890 | /// assert!(bananas.starts_with("bana")); | |
891 | /// assert!(!bananas.starts_with("nana")); | |
1a4d82fc | 892 | /// ``` |
85aaf69f | 893 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 894 | pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool { |
62682a34 | 895 | core_str::StrExt::starts_with(self, pat) |
1a4d82fc JJ |
896 | } |
897 | ||
92a42be0 SL |
898 | /// Returns `true` if the given `&str` is a suffix of this string slice. |
899 | /// | |
900 | /// Returns `false` if not. | |
1a4d82fc | 901 | /// |
c34b1796 | 902 | /// # Examples |
1a4d82fc | 903 | /// |
92a42be0 SL |
904 | /// Basic usage: |
905 | /// | |
1a4d82fc | 906 | /// ```rust |
92a42be0 SL |
907 | /// let bananas = "bananas"; |
908 | /// | |
909 | /// assert!(bananas.ends_with("anas")); | |
910 | /// assert!(!bananas.ends_with("nana")); | |
1a4d82fc | 911 | /// ``` |
85aaf69f | 912 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
913 | pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool |
914 | where P::Searcher: ReverseSearcher<'a> | |
915 | { | |
62682a34 | 916 | core_str::StrExt::ends_with(self, pat) |
1a4d82fc JJ |
917 | } |
918 | ||
92a42be0 SL |
919 | /// Returns the byte index of the first character of this string slice that |
920 | /// matches the pattern. | |
62682a34 | 921 | /// |
92a42be0 | 922 | /// Returns `None` if the pattern doesn't match. |
62682a34 | 923 | /// |
92a42be0 SL |
924 | /// The pattern can be a `&str`, [`char`], or a closure that determines if |
925 | /// a character matches. | |
926 | /// | |
927 | /// [`char`]: primitive.char.html | |
62682a34 SL |
928 | /// |
929 | /// # Examples | |
930 | /// | |
931 | /// Simple patterns: | |
932 | /// | |
933 | /// ``` | |
934 | /// let s = "Löwe 老虎 Léopard"; | |
935 | /// | |
936 | /// assert_eq!(s.find('L'), Some(0)); | |
937 | /// assert_eq!(s.find('é'), Some(14)); | |
938 | /// assert_eq!(s.find("Léopard"), Some(13)); | |
62682a34 SL |
939 | /// ``` |
940 | /// | |
941 | /// More complex patterns with closures: | |
942 | /// | |
943 | /// ``` | |
944 | /// let s = "Löwe 老虎 Léopard"; | |
945 | /// | |
946 | /// assert_eq!(s.find(char::is_whitespace), Some(5)); | |
947 | /// assert_eq!(s.find(char::is_lowercase), Some(1)); | |
948 | /// ``` | |
949 | /// | |
950 | /// Not finding the pattern: | |
951 | /// | |
952 | /// ``` | |
953 | /// let s = "Löwe 老虎 Léopard"; | |
954 | /// let x: &[_] = &['1', '2']; | |
955 | /// | |
956 | /// assert_eq!(s.find(x), None); | |
957 | /// ``` | |
958 | #[stable(feature = "rust1", since = "1.0.0")] | |
959 | pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> { | |
960 | core_str::StrExt::find(self, pat) | |
961 | } | |
962 | ||
92a42be0 SL |
963 | /// Returns the byte index of the last character of this string slice that |
964 | /// matches the pattern. | |
965 | /// | |
966 | /// Returns `None` if the pattern doesn't match. | |
62682a34 | 967 | /// |
92a42be0 SL |
968 | /// The pattern can be a `&str`, [`char`], or a closure that determines if |
969 | /// a character matches. | |
1a4d82fc | 970 | /// |
92a42be0 | 971 | /// [`char`]: primitive.char.html |
1a4d82fc | 972 | /// |
c34b1796 | 973 | /// # Examples |
1a4d82fc | 974 | /// |
9346a6ac | 975 | /// Simple patterns: |
1a4d82fc | 976 | /// |
c34b1796 | 977 | /// ``` |
62682a34 | 978 | /// let s = "Löwe 老虎 Léopard"; |
c34b1796 | 979 | /// |
62682a34 SL |
980 | /// assert_eq!(s.rfind('L'), Some(13)); |
981 | /// assert_eq!(s.rfind('é'), Some(14)); | |
c34b1796 AL |
982 | /// ``` |
983 | /// | |
9346a6ac | 984 | /// More complex patterns with closures: |
c34b1796 AL |
985 | /// |
986 | /// ``` | |
62682a34 SL |
987 | /// let s = "Löwe 老虎 Léopard"; |
988 | /// | |
989 | /// assert_eq!(s.rfind(char::is_whitespace), Some(12)); | |
990 | /// assert_eq!(s.rfind(char::is_lowercase), Some(20)); | |
991 | /// ``` | |
992 | /// | |
993 | /// Not finding the pattern: | |
994 | /// | |
995 | /// ``` | |
996 | /// let s = "Löwe 老虎 Léopard"; | |
997 | /// let x: &[_] = &['1', '2']; | |
998 | /// | |
999 | /// assert_eq!(s.rfind(x), None); | |
1a4d82fc | 1000 | /// ``` |
85aaf69f | 1001 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
1002 | pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> |
1003 | where P::Searcher: ReverseSearcher<'a> | |
c34b1796 | 1004 | { |
62682a34 | 1005 | core_str::StrExt::rfind(self, pat) |
1a4d82fc JJ |
1006 | } |
1007 | ||
92a42be0 SL |
1008 | /// An iterator over substrings of this string slice, separated by |
1009 | /// characters matched by a pattern. | |
1a4d82fc | 1010 | /// |
92a42be0 SL |
1011 | /// The pattern can be a `&str`, [`char`], or a closure that determines the |
1012 | /// split. | |
62682a34 SL |
1013 | /// |
1014 | /// # Iterator behavior | |
1015 | /// | |
92a42be0 SL |
1016 | /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern |
1017 | /// allows a reverse search and forward/reverse search yields the same | |
1018 | /// elements. This is true for, eg, [`char`] but not for `&str`. | |
1019 | /// | |
1020 | /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html | |
62682a34 SL |
1021 | /// |
1022 | /// If the pattern allows a reverse search but its results might differ | |
92a42be0 SL |
1023 | /// from a forward search, the [`rsplit()`] method can be used. |
1024 | /// | |
1025 | /// [`char`]: primitive.char.html | |
1026 | /// [`rsplit()`]: #method.rsplit | |
1a4d82fc | 1027 | /// |
c34b1796 | 1028 | /// # Examples |
1a4d82fc | 1029 | /// |
9346a6ac | 1030 | /// Simple patterns: |
1a4d82fc | 1031 | /// |
c34b1796 | 1032 | /// ``` |
62682a34 SL |
1033 | /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect(); |
1034 | /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]); | |
c34b1796 | 1035 | /// |
62682a34 SL |
1036 | /// let v: Vec<&str> = "".split('X').collect(); |
1037 | /// assert_eq!(v, [""]); | |
c34b1796 | 1038 | /// |
62682a34 SL |
1039 | /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect(); |
1040 | /// assert_eq!(v, ["lion", "", "tiger", "leopard"]); | |
c34b1796 | 1041 | /// |
62682a34 SL |
1042 | /// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect(); |
1043 | /// assert_eq!(v, ["lion", "tiger", "leopard"]); | |
1a4d82fc | 1044 | /// |
62682a34 SL |
1045 | /// let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect(); |
1046 | /// assert_eq!(v, ["abc", "def", "ghi"]); | |
1a4d82fc | 1047 | /// |
62682a34 SL |
1048 | /// let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect(); |
1049 | /// assert_eq!(v, ["lion", "tiger", "leopard"]); | |
1050 | /// ``` | |
1a4d82fc | 1051 | /// |
62682a34 | 1052 | /// A more complex pattern, using a closure: |
1a4d82fc | 1053 | /// |
c34b1796 | 1054 | /// ``` |
62682a34 SL |
1055 | /// let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect(); |
1056 | /// assert_eq!(v, ["abc", "def", "ghi"]); | |
c34b1796 AL |
1057 | /// ``` |
1058 | /// | |
62682a34 SL |
1059 | /// If a string contains multiple contiguous separators, you will end up |
1060 | /// with empty strings in the output: | |
c34b1796 AL |
1061 | /// |
1062 | /// ``` | |
62682a34 SL |
1063 | /// let x = "||||a||b|c".to_string(); |
1064 | /// let d: Vec<_> = x.split('|').collect(); | |
c34b1796 | 1065 | /// |
62682a34 SL |
1066 | /// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]); |
1067 | /// ``` | |
1a4d82fc | 1068 | /// |
62682a34 SL |
1069 | /// This can lead to possibly surprising behavior when whitespace is used |
1070 | /// as the separator. This code is correct: | |
1a4d82fc | 1071 | /// |
62682a34 SL |
1072 | /// ``` |
1073 | /// let x = " a b c".to_string(); | |
1074 | /// let d: Vec<_> = x.split(' ').collect(); | |
1a4d82fc | 1075 | /// |
62682a34 | 1076 | /// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]); |
c34b1796 | 1077 | /// ``` |
1a4d82fc | 1078 | /// |
62682a34 | 1079 | /// It does _not_ give you: |
1a4d82fc | 1080 | /// |
62682a34 SL |
1081 | /// ```rust,ignore |
1082 | /// assert_eq!(d, &["a", "b", "c"]); | |
1a4d82fc | 1083 | /// ``` |
b039eaaf | 1084 | /// |
92a42be0 | 1085 | /// Use [`split_whitespace()`] for this behavior. |
b039eaaf | 1086 | /// |
92a42be0 | 1087 | /// [`split_whitespace()`]: #method.split_whitespace |
62682a34 SL |
1088 | #[stable(feature = "rust1", since = "1.0.0")] |
1089 | pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> { | |
1090 | core_str::StrExt::split(self, pat) | |
1a4d82fc JJ |
1091 | } |
1092 | ||
92a42be0 SL |
1093 | /// An iterator over substrings of the given string slice, separated by |
1094 | /// characters matched by a pattern and yielded in reverse order. | |
1a4d82fc | 1095 | /// |
92a42be0 SL |
1096 | /// The pattern can be a `&str`, [`char`], or a closure that determines the |
1097 | /// split. | |
1098 | /// | |
1099 | /// [`char`]: primitive.char.html | |
1a4d82fc | 1100 | /// |
62682a34 | 1101 | /// # Iterator behavior |
1a4d82fc | 1102 | /// |
92a42be0 SL |
1103 | /// The returned iterator requires that the pattern supports a reverse |
1104 | /// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse | |
1105 | /// search yields the same elements. | |
1106 | /// | |
1107 | /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html | |
62682a34 | 1108 | /// |
92a42be0 SL |
1109 | /// For iterating from the front, the [`split()`] method can be used. |
1110 | /// | |
1111 | /// [`split()`]: #method.split | |
1a4d82fc | 1112 | /// |
c34b1796 AL |
1113 | /// # Examples |
1114 | /// | |
62682a34 | 1115 | /// Simple patterns: |
c34b1796 | 1116 | /// |
92a42be0 | 1117 | /// ``` |
62682a34 SL |
1118 | /// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect(); |
1119 | /// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]); | |
1a4d82fc | 1120 | /// |
62682a34 SL |
1121 | /// let v: Vec<&str> = "".rsplit('X').collect(); |
1122 | /// assert_eq!(v, [""]); | |
1123 | /// | |
1124 | /// let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect(); | |
1125 | /// assert_eq!(v, ["leopard", "tiger", "", "lion"]); | |
1126 | /// | |
1127 | /// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect(); | |
1128 | /// assert_eq!(v, ["leopard", "tiger", "lion"]); | |
1a4d82fc JJ |
1129 | /// ``` |
1130 | /// | |
62682a34 | 1131 | /// A more complex pattern, using a closure: |
1a4d82fc | 1132 | /// |
1a4d82fc | 1133 | /// ``` |
62682a34 SL |
1134 | /// let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect(); |
1135 | /// assert_eq!(v, ["ghi", "def", "abc"]); | |
1136 | /// ``` | |
1137 | #[stable(feature = "rust1", since = "1.0.0")] | |
1138 | pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P> | |
1139 | where P::Searcher: ReverseSearcher<'a> | |
1140 | { | |
1141 | core_str::StrExt::rsplit(self, pat) | |
1a4d82fc JJ |
1142 | } |
1143 | ||
92a42be0 SL |
1144 | /// An iterator over substrings of the given string slice, separated by |
1145 | /// characters matched by a pattern. | |
1a4d82fc | 1146 | /// |
92a42be0 SL |
1147 | /// The pattern can be a `&str`, [`char`], or a closure that determines the |
1148 | /// split. | |
1a4d82fc | 1149 | /// |
92a42be0 | 1150 | /// Equivalent to [`split()`], except that the trailing substring |
62682a34 | 1151 | /// is skipped if empty. |
1a4d82fc | 1152 | /// |
92a42be0 SL |
1153 | /// [`split()`]: #method.split |
1154 | /// | |
62682a34 SL |
1155 | /// This method can be used for string data that is _terminated_, |
1156 | /// rather than _separated_ by a pattern. | |
1a4d82fc | 1157 | /// |
62682a34 | 1158 | /// # Iterator behavior |
1a4d82fc | 1159 | /// |
92a42be0 SL |
1160 | /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern |
1161 | /// allows a reverse search and forward/reverse search yields the same | |
1162 | /// elements. This is true for, eg, [`char`] but not for `&str`. | |
1163 | /// | |
1164 | /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html | |
1165 | /// [`char`]: primitive.char.html | |
c34b1796 | 1166 | /// |
62682a34 | 1167 | /// If the pattern allows a reverse search but its results might differ |
92a42be0 SL |
1168 | /// from a forward search, the [`rsplit_terminator()`] method can be used. |
1169 | /// | |
1170 | /// [`rsplit_terminator()`]: #method.rsplit_terminator | |
1a4d82fc | 1171 | /// |
62682a34 | 1172 | /// # Examples |
1a4d82fc | 1173 | /// |
92a42be0 SL |
1174 | /// Basic usage: |
1175 | /// | |
c34b1796 | 1176 | /// ``` |
62682a34 SL |
1177 | /// let v: Vec<&str> = "A.B.".split_terminator('.').collect(); |
1178 | /// assert_eq!(v, ["A", "B"]); | |
1a4d82fc | 1179 | /// |
62682a34 SL |
1180 | /// let v: Vec<&str> = "A..B..".split_terminator(".").collect(); |
1181 | /// assert_eq!(v, ["A", "", "B", ""]); | |
c34b1796 | 1182 | /// ``` |
62682a34 SL |
1183 | #[stable(feature = "rust1", since = "1.0.0")] |
1184 | pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> { | |
1185 | core_str::StrExt::split_terminator(self, pat) | |
1a4d82fc JJ |
1186 | } |
1187 | ||
62682a34 SL |
1188 | /// An iterator over substrings of `self`, separated by characters |
1189 | /// matched by a pattern and yielded in reverse order. | |
c34b1796 | 1190 | /// |
62682a34 SL |
1191 | /// The pattern can be a simple `&str`, `char`, or a closure that |
1192 | /// determines the split. | |
1193 | /// Additional libraries might provide more complex patterns like | |
1194 | /// regular expressions. | |
1195 | /// | |
1196 | /// Equivalent to `split`, except that the trailing substring is | |
1197 | /// skipped if empty. | |
1198 | /// | |
1199 | /// This method can be used for string data that is _terminated_, | |
1200 | /// rather than _separated_ by a pattern. | |
1201 | /// | |
1202 | /// # Iterator behavior | |
1203 | /// | |
1204 | /// The returned iterator requires that the pattern supports a | |
1205 | /// reverse search, and it will be double ended if a forward/reverse | |
1206 | /// search yields the same elements. | |
c34b1796 | 1207 | /// |
92a42be0 SL |
1208 | /// For iterating from the front, the [`split_terminator()`] method can be |
1209 | /// used. | |
1210 | /// | |
1211 | /// [`split_terminator()`]: #method.split_terminator | |
c34b1796 AL |
1212 | /// |
1213 | /// # Examples | |
1214 | /// | |
1215 | /// ``` | |
62682a34 SL |
1216 | /// let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect(); |
1217 | /// assert_eq!(v, ["B", "A"]); | |
1218 | /// | |
1219 | /// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect(); | |
1220 | /// assert_eq!(v, ["", "B", "", "A"]); | |
c34b1796 | 1221 | /// ``` |
62682a34 SL |
1222 | #[stable(feature = "rust1", since = "1.0.0")] |
1223 | pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P> | |
1224 | where P::Searcher: ReverseSearcher<'a> | |
1225 | { | |
1226 | core_str::StrExt::rsplit_terminator(self, pat) | |
c34b1796 AL |
1227 | } |
1228 | ||
92a42be0 SL |
1229 | /// An iterator over substrings of the given string slice, separated by a |
1230 | /// pattern, restricted to returning at most `count` items. | |
1a4d82fc | 1231 | /// |
62682a34 | 1232 | /// The last element returned, if any, will contain the remainder of the |
92a42be0 SL |
1233 | /// string slice. |
1234 | /// | |
1235 | /// The pattern can be a `&str`, [`char`], or a closure that determines the | |
1236 | /// split. | |
1237 | /// | |
1238 | /// [`char`]: primitive.char.html | |
1a4d82fc | 1239 | /// |
62682a34 SL |
1240 | /// # Iterator behavior |
1241 | /// | |
1242 | /// The returned iterator will not be double ended, because it is | |
1243 | /// not efficient to support. | |
1244 | /// | |
92a42be0 SL |
1245 | /// If the pattern allows a reverse search, the [`rsplitn()`] method can be |
1246 | /// used. | |
1247 | /// | |
1248 | /// [`rsplitn()`]: #method.rsplitn | |
c34b1796 AL |
1249 | /// |
1250 | /// # Examples | |
1251 | /// | |
62682a34 SL |
1252 | /// Simple patterns: |
1253 | /// | |
c34b1796 | 1254 | /// ``` |
62682a34 SL |
1255 | /// let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect(); |
1256 | /// assert_eq!(v, ["Mary", "had", "a little lambda"]); | |
1257 | /// | |
1258 | /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect(); | |
1259 | /// assert_eq!(v, ["lion", "", "tigerXleopard"]); | |
1260 | /// | |
1261 | /// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect(); | |
1262 | /// assert_eq!(v, ["abcXdef"]); | |
1263 | /// | |
1264 | /// let v: Vec<&str> = "".splitn(1, 'X').collect(); | |
1265 | /// assert_eq!(v, [""]); | |
c34b1796 | 1266 | /// ``` |
1a4d82fc | 1267 | /// |
62682a34 | 1268 | /// A more complex pattern, using a closure: |
1a4d82fc | 1269 | /// |
c34b1796 | 1270 | /// ``` |
62682a34 SL |
1271 | /// let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect(); |
1272 | /// assert_eq!(v, ["abc", "defXghi"]); | |
1a4d82fc | 1273 | /// ``` |
85aaf69f | 1274 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
1275 | pub fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> { |
1276 | core_str::StrExt::splitn(self, count, pat) | |
1a4d82fc JJ |
1277 | } |
1278 | ||
92a42be0 SL |
1279 | /// An iterator over substrings of this string slice, separated by a |
1280 | /// pattern, starting from the end of the string, restricted to returning | |
62682a34 | 1281 | /// at most `count` items. |
1a4d82fc | 1282 | /// |
62682a34 | 1283 | /// The last element returned, if any, will contain the remainder of the |
92a42be0 | 1284 | /// string slice. |
1a4d82fc | 1285 | /// |
92a42be0 | 1286 | /// The pattern can be a `&str`, [`char`], or a closure that |
62682a34 | 1287 | /// determines the split. |
92a42be0 SL |
1288 | /// |
1289 | /// [`char`]: primitive.char.html | |
62682a34 SL |
1290 | /// |
1291 | /// # Iterator behavior | |
1292 | /// | |
1293 | /// The returned iterator will not be double ended, because it is not | |
1294 | /// efficient to support. | |
1295 | /// | |
92a42be0 SL |
1296 | /// For splitting from the front, the [`splitn()`] method can be used. |
1297 | /// | |
1298 | /// [`splitn()`]: #method.splitn | |
1a4d82fc | 1299 | /// |
c34b1796 | 1300 | /// # Examples |
1a4d82fc | 1301 | /// |
9346a6ac | 1302 | /// Simple patterns: |
c34b1796 AL |
1303 | /// |
1304 | /// ``` | |
62682a34 SL |
1305 | /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect(); |
1306 | /// assert_eq!(v, ["lamb", "little", "Mary had a"]); | |
1a4d82fc | 1307 | /// |
62682a34 SL |
1308 | /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect(); |
1309 | /// assert_eq!(v, ["leopard", "tiger", "lionX"]); | |
1a4d82fc | 1310 | /// |
62682a34 SL |
1311 | /// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect(); |
1312 | /// assert_eq!(v, ["leopard", "lion::tiger"]); | |
c34b1796 AL |
1313 | /// ``` |
1314 | /// | |
62682a34 | 1315 | /// A more complex pattern, using a closure: |
c34b1796 AL |
1316 | /// |
1317 | /// ``` | |
62682a34 SL |
1318 | /// let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect(); |
1319 | /// assert_eq!(v, ["ghi", "abc1def"]); | |
c34b1796 | 1320 | /// ``` |
62682a34 SL |
1321 | #[stable(feature = "rust1", since = "1.0.0")] |
1322 | pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> | |
1323 | where P::Searcher: ReverseSearcher<'a> | |
1324 | { | |
1325 | core_str::StrExt::rsplitn(self, count, pat) | |
1326 | } | |
1327 | ||
92a42be0 SL |
1328 | /// An iterator over the matches of a pattern within the given string |
1329 | /// slice. | |
1a4d82fc | 1330 | /// |
92a42be0 | 1331 | /// The pattern can be a `&str`, [`char`], or a closure that |
b039eaaf | 1332 | /// determines if a character matches. |
92a42be0 SL |
1333 | /// |
1334 | /// [`char`]: primitive.char.html | |
62682a34 SL |
1335 | /// |
1336 | /// # Iterator behavior | |
1337 | /// | |
92a42be0 SL |
1338 | /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern |
1339 | /// allows a reverse search and forward/reverse search yields the same | |
1340 | /// elements. This is true for, eg, [`char`] but not for `&str`. | |
1341 | /// | |
1342 | /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html | |
1343 | /// [`char`]: primitive.char.html | |
62682a34 SL |
1344 | /// |
1345 | /// If the pattern allows a reverse search but its results might differ | |
92a42be0 SL |
1346 | /// from a forward search, the [`rmatches()`] method can be used. |
1347 | /// | |
1348 | /// [`rmatches()`]: #method.rmatches | |
62682a34 SL |
1349 | /// |
1350 | /// # Examples | |
c34b1796 | 1351 | /// |
92a42be0 SL |
1352 | /// Basic usage: |
1353 | /// | |
c34b1796 | 1354 | /// ``` |
62682a34 SL |
1355 | /// let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect(); |
1356 | /// assert_eq!(v, ["abc", "abc", "abc"]); | |
c34b1796 | 1357 | /// |
62682a34 SL |
1358 | /// let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect(); |
1359 | /// assert_eq!(v, ["1", "2", "3"]); | |
1a4d82fc | 1360 | /// ``` |
62682a34 SL |
1361 | #[stable(feature = "str_matches", since = "1.2.0")] |
1362 | pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> { | |
1363 | core_str::StrExt::matches(self, pat) | |
1a4d82fc JJ |
1364 | } |
1365 | ||
92a42be0 SL |
1366 | /// An iterator over the matches of a pattern within this string slice, |
1367 | /// yielded in reverse order. | |
1a4d82fc | 1368 | /// |
92a42be0 SL |
1369 | /// The pattern can be a `&str`, [`char`], or a closure that determines if |
1370 | /// a character matches. | |
1371 | /// | |
1372 | /// [`char`]: primitive.char.html | |
1a4d82fc | 1373 | /// |
62682a34 | 1374 | /// # Iterator behavior |
1a4d82fc | 1375 | /// |
92a42be0 SL |
1376 | /// The returned iterator requires that the pattern supports a reverse |
1377 | /// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse | |
1378 | /// search yields the same elements. | |
1379 | /// | |
1380 | /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html | |
1a4d82fc | 1381 | /// |
92a42be0 SL |
1382 | /// For iterating from the front, the [`matches()`] method can be used. |
1383 | /// | |
1384 | /// [`matches`]: #method.matches | |
62682a34 SL |
1385 | /// |
1386 | /// # Examples | |
c34b1796 | 1387 | /// |
92a42be0 SL |
1388 | /// Basic usage: |
1389 | /// | |
c34b1796 | 1390 | /// ``` |
62682a34 SL |
1391 | /// let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect(); |
1392 | /// assert_eq!(v, ["abc", "abc", "abc"]); | |
1a4d82fc | 1393 | /// |
62682a34 SL |
1394 | /// let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect(); |
1395 | /// assert_eq!(v, ["3", "2", "1"]); | |
c34b1796 | 1396 | /// ``` |
62682a34 SL |
1397 | #[stable(feature = "str_matches", since = "1.2.0")] |
1398 | pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P> | |
1399 | where P::Searcher: ReverseSearcher<'a> | |
1400 | { | |
1401 | core_str::StrExt::rmatches(self, pat) | |
1402 | } | |
1403 | ||
92a42be0 SL |
1404 | /// An iterator over the disjoint matches of a pattern within this string |
1405 | /// slice as well as the index that the match starts at. | |
c34b1796 | 1406 | /// |
62682a34 | 1407 | /// For matches of `pat` within `self` that overlap, only the indices |
b039eaaf | 1408 | /// corresponding to the first match are returned. |
c34b1796 | 1409 | /// |
92a42be0 SL |
1410 | /// The pattern can be a `&str`, [`char`], or a closure that determines |
1411 | /// if a character matches. | |
1412 | /// | |
1413 | /// [`char`]: primitive.char.html | |
1a4d82fc | 1414 | /// |
62682a34 | 1415 | /// # Iterator behavior |
c34b1796 | 1416 | /// |
92a42be0 SL |
1417 | /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern |
1418 | /// allows a reverse search and forward/reverse search yields the same | |
1419 | /// elements. This is true for, eg, [`char`] but not for `&str`. | |
1420 | /// | |
1421 | /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html | |
62682a34 SL |
1422 | /// |
1423 | /// If the pattern allows a reverse search but its results might differ | |
92a42be0 SL |
1424 | /// from a forward search, the [`rmatch_indices()`] method can be used. |
1425 | /// | |
1426 | /// [`rmatch_indices()`]: #method.rmatch_indices | |
62682a34 SL |
1427 | /// |
1428 | /// # Examples | |
1a4d82fc | 1429 | /// |
92a42be0 | 1430 | /// Basic usage: |
c1a9b12d | 1431 | /// |
92a42be0 | 1432 | /// ``` |
b039eaaf SL |
1433 | /// let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect(); |
1434 | /// assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]); | |
c34b1796 | 1435 | /// |
b039eaaf SL |
1436 | /// let v: Vec<_> = "1abcabc2".match_indices("abc").collect(); |
1437 | /// assert_eq!(v, [(1, "abc"), (4, "abc")]); | |
62682a34 | 1438 | /// |
b039eaaf SL |
1439 | /// let v: Vec<_> = "ababa".match_indices("aba").collect(); |
1440 | /// assert_eq!(v, [(0, "aba")]); // only the first `aba` | |
1a4d82fc | 1441 | /// ``` |
b039eaaf | 1442 | #[stable(feature = "str_match_indices", since = "1.5.0")] |
62682a34 SL |
1443 | pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> { |
1444 | core_str::StrExt::match_indices(self, pat) | |
1a4d82fc JJ |
1445 | } |
1446 | ||
b039eaaf SL |
1447 | /// An iterator over the disjoint matches of a pattern within `self`, |
1448 | /// yielded in reverse order along with the index of the match. | |
1a4d82fc | 1449 | /// |
62682a34 | 1450 | /// For matches of `pat` within `self` that overlap, only the indices |
b039eaaf | 1451 | /// corresponding to the last match are returned. |
1a4d82fc | 1452 | /// |
92a42be0 SL |
1453 | /// The pattern can be a `&str`, [`char`], or a closure that determines if a |
1454 | /// character matches. | |
1455 | /// | |
1456 | /// [`char`]: primitive.char.html | |
62682a34 SL |
1457 | /// |
1458 | /// # Iterator behavior | |
1459 | /// | |
b039eaaf | 1460 | /// The returned iterator requires that the pattern supports a reverse |
92a42be0 SL |
1461 | /// search, and it will be a `[DoubleEndedIterator]` if a forward/reverse |
1462 | /// search yields the same elements. | |
62682a34 | 1463 | /// |
92a42be0 SL |
1464 | /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html |
1465 | /// | |
1466 | /// For iterating from the front, the [`match_indices()`] method can be used. | |
1467 | /// | |
1468 | /// [`match_indices()`]: #method.match_indices | |
1a4d82fc | 1469 | /// |
c34b1796 | 1470 | /// # Examples |
1a4d82fc | 1471 | /// |
92a42be0 | 1472 | /// Basic usage: |
c1a9b12d | 1473 | /// |
92a42be0 | 1474 | /// ``` |
b039eaaf SL |
1475 | /// let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect(); |
1476 | /// assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]); | |
1a4d82fc | 1477 | /// |
b039eaaf SL |
1478 | /// let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect(); |
1479 | /// assert_eq!(v, [(4, "abc"), (1, "abc")]); | |
c34b1796 | 1480 | /// |
b039eaaf SL |
1481 | /// let v: Vec<_> = "ababa".rmatch_indices("aba").collect(); |
1482 | /// assert_eq!(v, [(2, "aba")]); // only the last `aba` | |
1a4d82fc | 1483 | /// ``` |
b039eaaf | 1484 | #[stable(feature = "str_match_indices", since = "1.5.0")] |
62682a34 SL |
1485 | pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P> |
1486 | where P::Searcher: ReverseSearcher<'a> | |
1487 | { | |
1488 | core_str::StrExt::rmatch_indices(self, pat) | |
1a4d82fc JJ |
1489 | } |
1490 | ||
92a42be0 SL |
1491 | /// Returns a string slice with leading and trailing whitespace removed. |
1492 | /// | |
1493 | /// 'Whitespace' is defined according to the terms of the Unicode Derived | |
1494 | /// Core Property `White_Space`. | |
1a4d82fc | 1495 | /// |
c34b1796 AL |
1496 | /// # Examples |
1497 | /// | |
92a42be0 SL |
1498 | /// Basic usage: |
1499 | /// | |
c34b1796 | 1500 | /// ``` |
62682a34 | 1501 | /// let s = " Hello\tworld\t"; |
92a42be0 SL |
1502 | /// |
1503 | /// assert_eq!("Hello\tworld", s.trim()); | |
c34b1796 | 1504 | /// ``` |
85aaf69f | 1505 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
1506 | pub fn trim(&self) -> &str { |
1507 | UnicodeStr::trim(self) | |
1a4d82fc JJ |
1508 | } |
1509 | ||
92a42be0 SL |
1510 | /// Returns a string slice with leading whitespace removed. |
1511 | /// | |
1512 | /// 'Whitespace' is defined according to the terms of the Unicode Derived | |
1513 | /// Core Property `White_Space`. | |
1a4d82fc | 1514 | /// |
c34b1796 | 1515 | /// # Examples |
1a4d82fc | 1516 | /// |
92a42be0 SL |
1517 | /// Basic usage: |
1518 | /// | |
1a4d82fc | 1519 | /// ``` |
62682a34 | 1520 | /// let s = " Hello\tworld\t"; |
92a42be0 SL |
1521 | /// |
1522 | /// assert_eq!("Hello\tworld\t", s.trim_left()); | |
1a4d82fc | 1523 | /// ``` |
85aaf69f | 1524 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
1525 | pub fn trim_left(&self) -> &str { |
1526 | UnicodeStr::trim_left(self) | |
1a4d82fc JJ |
1527 | } |
1528 | ||
92a42be0 SL |
1529 | /// Returns a string slice with trailing whitespace removed. |
1530 | /// | |
1531 | /// 'Whitespace' is defined according to the terms of the Unicode Derived | |
1532 | /// Core Property `White_Space`. | |
1a4d82fc | 1533 | /// |
c34b1796 | 1534 | /// # Examples |
1a4d82fc | 1535 | /// |
92a42be0 SL |
1536 | /// Basic usage: |
1537 | /// | |
1a4d82fc | 1538 | /// ``` |
62682a34 | 1539 | /// let s = " Hello\tworld\t"; |
92a42be0 SL |
1540 | /// |
1541 | /// assert_eq!(" Hello\tworld", s.trim_right()); | |
1a4d82fc | 1542 | /// ``` |
85aaf69f | 1543 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
1544 | pub fn trim_right(&self) -> &str { |
1545 | UnicodeStr::trim_right(self) | |
1a4d82fc JJ |
1546 | } |
1547 | ||
92a42be0 SL |
1548 | /// Returns a string slice with all prefixes and suffixes that match a |
1549 | /// pattern repeatedly removed. | |
c34b1796 | 1550 | /// |
92a42be0 | 1551 | /// The pattern can be a `&str`, [`char`], or a closure that determines |
b039eaaf | 1552 | /// if a character matches. |
c34b1796 | 1553 | /// |
92a42be0 SL |
1554 | /// [`char`]: primtive.char.html |
1555 | /// | |
62682a34 | 1556 | /// # Examples |
1a4d82fc | 1557 | /// |
62682a34 | 1558 | /// Simple patterns: |
1a4d82fc JJ |
1559 | /// |
1560 | /// ``` | |
62682a34 SL |
1561 | /// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar"); |
1562 | /// assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar"); | |
1563 | /// | |
1564 | /// let x: &[_] = &['1', '2']; | |
1565 | /// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar"); | |
c34b1796 AL |
1566 | /// ``` |
1567 | /// | |
62682a34 | 1568 | /// A more complex pattern, using a closure: |
c34b1796 AL |
1569 | /// |
1570 | /// ``` | |
62682a34 | 1571 | /// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar"); |
1a4d82fc | 1572 | /// ``` |
85aaf69f | 1573 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
1574 | pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str |
1575 | where P::Searcher: DoubleEndedSearcher<'a> | |
1576 | { | |
1577 | core_str::StrExt::trim_matches(self, pat) | |
1a4d82fc JJ |
1578 | } |
1579 | ||
92a42be0 | 1580 | /// Returns a string slice with all prefixes that match a pattern |
62682a34 | 1581 | /// repeatedly removed. |
1a4d82fc | 1582 | /// |
92a42be0 SL |
1583 | /// The pattern can be a `&str`, [`char`], or a closure that determines if |
1584 | /// a character matches. | |
1585 | /// | |
1586 | /// [`char`]: primitive.char.html | |
1a4d82fc | 1587 | /// |
c34b1796 | 1588 | /// # Examples |
1a4d82fc | 1589 | /// |
92a42be0 SL |
1590 | /// Basic usage: |
1591 | /// | |
c34b1796 | 1592 | /// ``` |
62682a34 SL |
1593 | /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11"); |
1594 | /// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123"); | |
c34b1796 | 1595 | /// |
62682a34 SL |
1596 | /// let x: &[_] = &['1', '2']; |
1597 | /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12"); | |
1a4d82fc | 1598 | /// ``` |
62682a34 SL |
1599 | #[stable(feature = "rust1", since = "1.0.0")] |
1600 | pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { | |
1601 | core_str::StrExt::trim_left_matches(self, pat) | |
1a4d82fc JJ |
1602 | } |
1603 | ||
92a42be0 | 1604 | /// Returns a string slice with all suffixes that match a pattern |
62682a34 SL |
1605 | /// repeatedly removed. |
1606 | /// | |
92a42be0 | 1607 | /// The pattern can be a `&str`, [`char`], or a closure that |
b039eaaf | 1608 | /// determines if a character matches. |
1a4d82fc | 1609 | /// |
92a42be0 SL |
1610 | /// [`char`]: primitive.char.html |
1611 | /// | |
c34b1796 | 1612 | /// # Examples |
1a4d82fc | 1613 | /// |
62682a34 SL |
1614 | /// Simple patterns: |
1615 | /// | |
c34b1796 | 1616 | /// ``` |
62682a34 SL |
1617 | /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar"); |
1618 | /// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar"); | |
c34b1796 | 1619 | /// |
62682a34 SL |
1620 | /// let x: &[_] = &['1', '2']; |
1621 | /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar"); | |
1a4d82fc | 1622 | /// ``` |
1a4d82fc | 1623 | /// |
62682a34 | 1624 | /// A more complex pattern, using a closure: |
c34b1796 AL |
1625 | /// |
1626 | /// ``` | |
62682a34 | 1627 | /// assert_eq!("1fooX".trim_left_matches(|c| c == '1' || c == 'X'), "fooX"); |
1a4d82fc | 1628 | /// ``` |
62682a34 SL |
1629 | #[stable(feature = "rust1", since = "1.0.0")] |
1630 | pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str | |
1631 | where P::Searcher: ReverseSearcher<'a> | |
1632 | { | |
1633 | core_str::StrExt::trim_right_matches(self, pat) | |
1a4d82fc JJ |
1634 | } |
1635 | ||
92a42be0 SL |
1636 | /// Parses this string slice into another type. |
1637 | /// | |
1638 | /// Because `parse()` is so general, it can cause problems with type | |
1639 | /// inference. As such, `parse()` is one of the few times you'll see | |
1640 | /// the syntax affectionately known as the 'turbofish': `::<>`. This | |
1641 | /// helps the inference algorithm understand specifically which type | |
1642 | /// you're trying to parse into. | |
1643 | /// | |
1644 | /// `parse()` can parse any type that implements the [`FromStr`] trait. | |
1645 | /// | |
1646 | /// [`FromStr`]: trait.FromStr.html | |
d9579d0f | 1647 | /// |
62682a34 | 1648 | /// # Failure |
d9579d0f | 1649 | /// |
92a42be0 SL |
1650 | /// Will return `Err` if it's not possible to parse this string slice into |
1651 | /// the desired type. | |
1a4d82fc | 1652 | /// |
62682a34 | 1653 | /// # Example |
c34b1796 | 1654 | /// |
92a42be0 SL |
1655 | /// Basic usage |
1656 | /// | |
62682a34 | 1657 | /// ``` |
92a42be0 SL |
1658 | /// let four: u32 = "4".parse().unwrap(); |
1659 | /// | |
1660 | /// assert_eq!(4, four); | |
1661 | /// ``` | |
1662 | /// | |
1663 | /// Using the 'turbofish' instead of annotationg `four`: | |
1664 | /// | |
62682a34 | 1665 | /// ``` |
92a42be0 | 1666 | /// let four = "4".parse::<u32>(); |
c34b1796 | 1667 | /// |
92a42be0 SL |
1668 | /// assert_eq!(Ok(4), four); |
1669 | /// ``` | |
1670 | /// | |
1671 | /// Failing to parse: | |
c34b1796 AL |
1672 | /// |
1673 | /// ``` | |
92a42be0 SL |
1674 | /// let nope = "j".parse::<u32>(); |
1675 | /// | |
1676 | /// assert!(nope.is_err()); | |
c34b1796 | 1677 | /// ``` |
62682a34 | 1678 | #[inline] |
85aaf69f | 1679 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
1680 | pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> { |
1681 | core_str::StrExt::parse(self) | |
1a4d82fc JJ |
1682 | } |
1683 | ||
62682a34 SL |
1684 | /// Replaces all occurrences of one string with another. |
1685 | /// | |
92a42be0 SL |
1686 | /// `replace` creates a new [`String`], and copies the data from this string slice into it. |
1687 | /// While doing so, it attempts to find a sub-`&str`. If it finds it, it replaces it with | |
1688 | /// the replacement string slice. | |
1689 | /// | |
1690 | /// [`String`]: string/struct.String.html | |
c34b1796 AL |
1691 | /// |
1692 | /// # Examples | |
1693 | /// | |
92a42be0 SL |
1694 | /// Basic usage: |
1695 | /// | |
c34b1796 | 1696 | /// ``` |
62682a34 SL |
1697 | /// let s = "this is old"; |
1698 | /// | |
92a42be0 | 1699 | /// assert_eq!("this is new", s.replace("old", "new")); |
c34b1796 | 1700 | /// ``` |
c34b1796 | 1701 | /// |
62682a34 | 1702 | /// When a `&str` isn't found: |
c34b1796 AL |
1703 | /// |
1704 | /// ``` | |
62682a34 | 1705 | /// let s = "this is old"; |
92a42be0 | 1706 | /// assert_eq!(s, s.replace("cookie monster", "little lamb")); |
c34b1796 | 1707 | /// ``` |
85aaf69f | 1708 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 SL |
1709 | pub fn replace(&self, from: &str, to: &str) -> String { |
1710 | let mut result = String::new(); | |
1711 | let mut last_end = 0; | |
b039eaaf | 1712 | for (start, part) in self.match_indices(from) { |
62682a34 SL |
1713 | result.push_str(unsafe { self.slice_unchecked(last_end, start) }); |
1714 | result.push_str(to); | |
b039eaaf | 1715 | last_end = start + part.len(); |
62682a34 SL |
1716 | } |
1717 | result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) }); | |
1718 | result | |
1a4d82fc | 1719 | } |
1a4d82fc | 1720 | |
92a42be0 SL |
1721 | /// Returns the lowercase equivalent of this string slice, as a new `String`. |
1722 | /// | |
1723 | /// 'Lowercase' is defined according to the terms of the Unicode Derived Core Property | |
1724 | /// `Lowercase`. | |
c34b1796 AL |
1725 | /// |
1726 | /// # Examples | |
1727 | /// | |
92a42be0 SL |
1728 | /// Basic usage: |
1729 | /// | |
62682a34 | 1730 | /// ``` |
c34b1796 | 1731 | /// let s = "HELLO"; |
92a42be0 SL |
1732 | /// |
1733 | /// assert_eq!("hello", s.to_lowercase()); | |
1734 | /// ``` | |
1735 | /// | |
1736 | /// A tricky example, with sigma: | |
1737 | /// | |
1738 | /// ``` | |
1739 | /// let sigma = "Σ"; | |
1740 | /// | |
1741 | /// assert_eq!("σ", sigma.to_lowercase()); | |
1742 | /// | |
1743 | /// // but at the end of a word, it's ς, not σ: | |
1744 | /// let odysseus = "ὈΔΥΣΣΕΎΣ"; | |
1745 | /// | |
1746 | /// assert_eq!("ὀδυσσεύς", odysseus.to_lowercase()); | |
1747 | /// ``` | |
1748 | /// | |
1749 | /// Languages without case are not changed: | |
1750 | /// | |
1751 | /// ``` | |
1752 | /// let new_year = "农历新年"; | |
1753 | /// | |
1754 | /// assert_eq!(new_year, new_year.to_lowercase()); | |
62682a34 SL |
1755 | /// ``` |
1756 | #[stable(feature = "unicode_case_mapping", since = "1.2.0")] | |
c34b1796 AL |
1757 | pub fn to_lowercase(&self) -> String { |
1758 | let mut s = String::with_capacity(self.len()); | |
62682a34 SL |
1759 | for (i, c) in self[..].char_indices() { |
1760 | if c == 'Σ' { | |
1761 | // Σ maps to σ, except at the end of a word where it maps to ς. | |
1762 | // This is the only conditional (contextual) but language-independent mapping | |
1763 | // in `SpecialCasing.txt`, | |
1764 | // so hard-code it rather than have a generic "condition" mechanim. | |
1765 | // See https://github.com/rust-lang/rust/issues/26035 | |
1766 | map_uppercase_sigma(self, i, &mut s) | |
1767 | } else { | |
1768 | s.extend(c.to_lowercase()); | |
1769 | } | |
1770 | } | |
c34b1796 | 1771 | return s; |
62682a34 SL |
1772 | |
1773 | fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) { | |
1774 | // See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 | |
1775 | // for the definition of `Final_Sigma`. | |
1776 | debug_assert!('Σ'.len_utf8() == 2); | |
92a42be0 SL |
1777 | let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) && |
1778 | !case_ignoreable_then_cased(from[i + 2..].chars()); | |
1779 | to.push_str(if is_word_final { | |
1780 | "ς" | |
1781 | } else { | |
1782 | "σ" | |
1783 | }); | |
62682a34 SL |
1784 | } |
1785 | ||
92a42be0 | 1786 | fn case_ignoreable_then_cased<I: Iterator<Item = char>>(iter: I) -> bool { |
62682a34 SL |
1787 | use rustc_unicode::derived_property::{Cased, Case_Ignorable}; |
1788 | match iter.skip_while(|&c| Case_Ignorable(c)).next() { | |
1789 | Some(c) => Cased(c), | |
1790 | None => false, | |
1791 | } | |
1792 | } | |
1a4d82fc JJ |
1793 | } |
1794 | ||
92a42be0 SL |
1795 | /// Returns the uppercase equivalent of this string slice, as a new `String`. |
1796 | /// | |
1797 | /// 'Uppercase' is defined according to the terms of the Unicode Derived Core Property | |
1798 | /// `Uppercase`. | |
c34b1796 AL |
1799 | /// |
1800 | /// # Examples | |
1801 | /// | |
92a42be0 SL |
1802 | /// Basic usage: |
1803 | /// | |
62682a34 | 1804 | /// ``` |
c34b1796 | 1805 | /// let s = "hello"; |
92a42be0 SL |
1806 | /// |
1807 | /// assert_eq!("HELLO", s.to_uppercase()); | |
1808 | /// ``` | |
1809 | /// | |
1810 | /// Scripts without case are not changed: | |
1811 | /// | |
1812 | /// ``` | |
1813 | /// let new_year = "农历新年"; | |
1814 | /// | |
1815 | /// assert_eq!(new_year, new_year.to_uppercase()); | |
62682a34 SL |
1816 | /// ``` |
1817 | #[stable(feature = "unicode_case_mapping", since = "1.2.0")] | |
c34b1796 AL |
1818 | pub fn to_uppercase(&self) -> String { |
1819 | let mut s = String::with_capacity(self.len()); | |
62682a34 | 1820 | s.extend(self.chars().flat_map(|c| c.to_uppercase())); |
c34b1796 | 1821 | return s; |
1a4d82fc | 1822 | } |
62682a34 SL |
1823 | |
1824 | /// Escapes each char in `s` with `char::escape_default`. | |
1825 | #[unstable(feature = "str_escape", | |
e9174d1e SL |
1826 | reason = "return type may change to be an iterator", |
1827 | issue = "27791")] | |
62682a34 SL |
1828 | pub fn escape_default(&self) -> String { |
1829 | self.chars().flat_map(|c| c.escape_default()).collect() | |
1830 | } | |
1831 | ||
1832 | /// Escapes each char in `s` with `char::escape_unicode`. | |
1833 | #[unstable(feature = "str_escape", | |
e9174d1e SL |
1834 | reason = "return type may change to be an iterator", |
1835 | issue = "27791")] | |
62682a34 SL |
1836 | pub fn escape_unicode(&self) -> String { |
1837 | self.chars().flat_map(|c| c.escape_unicode()).collect() | |
1838 | } | |
c1a9b12d | 1839 | |
92a42be0 SL |
1840 | /// Converts a `Box<str>` into a `String` without copying or allocating. |
1841 | /// | |
1842 | /// # Examples | |
1843 | /// | |
1844 | /// Basic usage: | |
1845 | /// | |
1846 | /// ``` | |
1847 | /// let string = String::from("birthday gift"); | |
1848 | /// let boxed_str = string.clone().into_boxed_str(); | |
1849 | /// | |
1850 | /// assert_eq!(boxed_str.into_string(), string); | |
1851 | /// ``` | |
e9174d1e | 1852 | #[stable(feature = "box_str", since = "1.4.0")] |
c1a9b12d SL |
1853 | pub fn into_string(self: Box<str>) -> String { |
1854 | unsafe { | |
1855 | let slice = mem::transmute::<Box<str>, Box<[u8]>>(self); | |
1856 | String::from_utf8_unchecked(slice.into_vec()) | |
1857 | } | |
1858 | } | |
1a4d82fc | 1859 | } |