1 | //! Trait implementations for `str`. |
2 | |
3 | use super::ParseBoolError; |
4 | use crate::cmp::Ordering; |
5 | use crate::intrinsics::unchecked_sub; |
6 | use crate::slice::SliceIndex; |
7 | use crate::ub_checks::assert_unsafe_precondition; |
8 | use crate::{ops, ptr, range}; |
9 | |
10 | /// Implements ordering of strings. |
11 | /// |
12 | /// Strings are ordered [lexicographically](Ord#lexicographical-comparison) by their byte values. This orders Unicode code |
13 | /// points based on their positions in the code charts. This is not necessarily the same as |
14 | /// "alphabetical" order, which varies by language and locale. Sorting strings according to |
15 | /// culturally-accepted standards requires locale-specific data that is outside the scope of |
16 | /// the `str` type. |
17 | #[stable (feature = "rust1" , since = "1.0.0" )] |
18 | impl Ord for str { |
19 | #[inline ] |
20 | fn cmp(&self, other: &str) -> Ordering { |
21 | self.as_bytes().cmp(other.as_bytes()) |
22 | } |
23 | } |
24 | |
25 | #[stable (feature = "rust1" , since = "1.0.0" )] |
26 | impl PartialEq for str { |
27 | #[inline ] |
28 | fn eq(&self, other: &str) -> bool { |
29 | self.as_bytes() == other.as_bytes() |
30 | } |
31 | } |
32 | |
33 | #[stable (feature = "rust1" , since = "1.0.0" )] |
34 | impl Eq for str {} |
35 | |
36 | /// Implements comparison operations on strings. |
37 | /// |
38 | /// Strings are compared [lexicographically](Ord#lexicographical-comparison) by their byte values. This compares Unicode code |
39 | /// points based on their positions in the code charts. This is not necessarily the same as |
40 | /// "alphabetical" order, which varies by language and locale. Comparing strings according to |
41 | /// culturally-accepted standards requires locale-specific data that is outside the scope of |
42 | /// the `str` type. |
43 | #[stable (feature = "rust1" , since = "1.0.0" )] |
44 | impl PartialOrd for str { |
45 | #[inline ] |
46 | fn partial_cmp(&self, other: &str) -> Option<Ordering> { |
47 | Some(self.cmp(other)) |
48 | } |
49 | } |
50 | |
51 | #[stable (feature = "rust1" , since = "1.0.0" )] |
52 | impl<I> ops::Index<I> for str |
53 | where |
54 | I: SliceIndex<str>, |
55 | { |
56 | type Output = I::Output; |
57 | |
58 | #[inline ] |
59 | fn index(&self, index: I) -> &I::Output { |
60 | index.index(self) |
61 | } |
62 | } |
63 | |
64 | #[stable (feature = "rust1" , since = "1.0.0" )] |
65 | impl<I> ops::IndexMut<I> for str |
66 | where |
67 | I: SliceIndex<str>, |
68 | { |
69 | #[inline ] |
70 | fn index_mut(&mut self, index: I) -> &mut I::Output { |
71 | index.index_mut(self) |
72 | } |
73 | } |
74 | |
75 | #[inline (never)] |
76 | #[cold ] |
77 | #[track_caller ] |
78 | const fn str_index_overflow_fail() -> ! { |
79 | panic!("attempted to index str up to maximum usize" ); |
80 | } |
81 | |
82 | /// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`. |
83 | /// |
84 | /// Returns a slice of the whole string, i.e., returns `&self` or `&mut |
85 | /// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike |
86 | /// other indexing operations, this can never panic. |
87 | /// |
88 | /// This operation is *O*(1). |
89 | /// |
90 | /// Prior to 1.20.0, these indexing operations were still supported by |
91 | /// direct implementation of `Index` and `IndexMut`. |
92 | /// |
93 | /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. |
94 | #[stable (feature = "str_checked_slicing" , since = "1.20.0" )] |
95 | unsafe impl SliceIndex<str> for ops::RangeFull { |
96 | type Output = str; |
97 | #[inline ] |
98 | fn get(self, slice: &str) -> Option<&Self::Output> { |
99 | Some(slice) |
100 | } |
101 | #[inline ] |
102 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
103 | Some(slice) |
104 | } |
105 | #[inline ] |
106 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
107 | slice |
108 | } |
109 | #[inline ] |
110 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
111 | slice |
112 | } |
113 | #[inline ] |
114 | fn index(self, slice: &str) -> &Self::Output { |
115 | slice |
116 | } |
117 | #[inline ] |
118 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
119 | slice |
120 | } |
121 | } |
122 | |
123 | /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut |
124 | /// self[begin .. end]`. |
125 | /// |
126 | /// Returns a slice of the given string from the byte range |
127 | /// [`begin`, `end`). |
128 | /// |
129 | /// This operation is *O*(1). |
130 | /// |
131 | /// Prior to 1.20.0, these indexing operations were still supported by |
132 | /// direct implementation of `Index` and `IndexMut`. |
133 | /// |
134 | /// # Panics |
135 | /// |
136 | /// Panics if `begin` or `end` does not point to the starting byte offset of |
137 | /// a character (as defined by `is_char_boundary`), if `begin > end`, or if |
138 | /// `end > len`. |
139 | /// |
140 | /// # Examples |
141 | /// |
142 | /// ``` |
143 | /// let s = "Löwe 老虎 Léopard" ; |
144 | /// assert_eq!(&s[0 .. 1], "L" ); |
145 | /// |
146 | /// assert_eq!(&s[1 .. 9], "öwe 老" ); |
147 | /// |
148 | /// // these will panic: |
149 | /// // byte 2 lies within `ö`: |
150 | /// // &s[2 ..3]; |
151 | /// |
152 | /// // byte 8 lies within `老` |
153 | /// // &s[1 .. 8]; |
154 | /// |
155 | /// // byte 100 is outside the string |
156 | /// // &s[3 .. 100]; |
157 | /// ``` |
158 | #[stable (feature = "str_checked_slicing" , since = "1.20.0" )] |
159 | unsafe impl SliceIndex<str> for ops::Range<usize> { |
160 | type Output = str; |
161 | #[inline ] |
162 | fn get(self, slice: &str) -> Option<&Self::Output> { |
163 | if self.start <= self.end |
164 | && slice.is_char_boundary(self.start) |
165 | && slice.is_char_boundary(self.end) |
166 | { |
167 | // SAFETY: just checked that `start` and `end` are on a char boundary, |
168 | // and we are passing in a safe reference, so the return value will also be one. |
169 | // We also checked char boundaries, so this is valid UTF-8. |
170 | Some(unsafe { &*self.get_unchecked(slice) }) |
171 | } else { |
172 | None |
173 | } |
174 | } |
175 | #[inline ] |
176 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
177 | if self.start <= self.end |
178 | && slice.is_char_boundary(self.start) |
179 | && slice.is_char_boundary(self.end) |
180 | { |
181 | // SAFETY: just checked that `start` and `end` are on a char boundary. |
182 | // We know the pointer is unique because we got it from `slice`. |
183 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
184 | } else { |
185 | None |
186 | } |
187 | } |
188 | #[inline ] |
189 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
190 | let slice = slice as *const [u8]; |
191 | |
192 | assert_unsafe_precondition!( |
193 | // We'd like to check that the bounds are on char boundaries, |
194 | // but there's not really a way to do so without reading |
195 | // behind the pointer, which has aliasing implications. |
196 | // It's also not possible to move this check up to |
197 | // `str::get_unchecked` without adding a special function |
198 | // to `SliceIndex` just for this. |
199 | check_library_ub, |
200 | "str::get_unchecked requires that the range is within the string slice" , |
201 | ( |
202 | start: usize = self.start, |
203 | end: usize = self.end, |
204 | len: usize = slice.len() |
205 | ) => end >= start && end <= len, |
206 | ); |
207 | |
208 | // SAFETY: the caller guarantees that `self` is in bounds of `slice` |
209 | // which satisfies all the conditions for `add`. |
210 | unsafe { |
211 | let new_len = unchecked_sub(self.end, self.start); |
212 | ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str |
213 | } |
214 | } |
215 | #[inline ] |
216 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
217 | let slice = slice as *mut [u8]; |
218 | |
219 | assert_unsafe_precondition!( |
220 | check_library_ub, |
221 | "str::get_unchecked_mut requires that the range is within the string slice" , |
222 | ( |
223 | start: usize = self.start, |
224 | end: usize = self.end, |
225 | len: usize = slice.len() |
226 | ) => end >= start && end <= len, |
227 | ); |
228 | |
229 | // SAFETY: see comments for `get_unchecked`. |
230 | unsafe { |
231 | let new_len = unchecked_sub(self.end, self.start); |
232 | ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str |
233 | } |
234 | } |
235 | #[inline ] |
236 | fn index(self, slice: &str) -> &Self::Output { |
237 | let (start, end) = (self.start, self.end); |
238 | match self.get(slice) { |
239 | Some(s) => s, |
240 | None => super::slice_error_fail(slice, start, end), |
241 | } |
242 | } |
243 | #[inline ] |
244 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
245 | // is_char_boundary checks that the index is in [0, .len()] |
246 | // cannot reuse `get` as above, because of NLL trouble |
247 | if self.start <= self.end |
248 | && slice.is_char_boundary(self.start) |
249 | && slice.is_char_boundary(self.end) |
250 | { |
251 | // SAFETY: just checked that `start` and `end` are on a char boundary, |
252 | // and we are passing in a safe reference, so the return value will also be one. |
253 | unsafe { &mut *self.get_unchecked_mut(slice) } |
254 | } else { |
255 | super::slice_error_fail(slice, self.start, self.end) |
256 | } |
257 | } |
258 | } |
259 | |
260 | #[unstable (feature = "new_range_api" , issue = "125687" )] |
261 | unsafe impl SliceIndex<str> for range::Range<usize> { |
262 | type Output = str; |
263 | #[inline ] |
264 | fn get(self, slice: &str) -> Option<&Self::Output> { |
265 | if self.start <= self.end |
266 | && slice.is_char_boundary(self.start) |
267 | && slice.is_char_boundary(self.end) |
268 | { |
269 | // SAFETY: just checked that `start` and `end` are on a char boundary, |
270 | // and we are passing in a safe reference, so the return value will also be one. |
271 | // We also checked char boundaries, so this is valid UTF-8. |
272 | Some(unsafe { &*self.get_unchecked(slice) }) |
273 | } else { |
274 | None |
275 | } |
276 | } |
277 | #[inline ] |
278 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
279 | if self.start <= self.end |
280 | && slice.is_char_boundary(self.start) |
281 | && slice.is_char_boundary(self.end) |
282 | { |
283 | // SAFETY: just checked that `start` and `end` are on a char boundary. |
284 | // We know the pointer is unique because we got it from `slice`. |
285 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
286 | } else { |
287 | None |
288 | } |
289 | } |
290 | #[inline ] |
291 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
292 | let slice = slice as *const [u8]; |
293 | |
294 | assert_unsafe_precondition!( |
295 | // We'd like to check that the bounds are on char boundaries, |
296 | // but there's not really a way to do so without reading |
297 | // behind the pointer, which has aliasing implications. |
298 | // It's also not possible to move this check up to |
299 | // `str::get_unchecked` without adding a special function |
300 | // to `SliceIndex` just for this. |
301 | check_library_ub, |
302 | "str::get_unchecked requires that the range is within the string slice" , |
303 | ( |
304 | start: usize = self.start, |
305 | end: usize = self.end, |
306 | len: usize = slice.len() |
307 | ) => end >= start && end <= len, |
308 | ); |
309 | |
310 | // SAFETY: the caller guarantees that `self` is in bounds of `slice` |
311 | // which satisfies all the conditions for `add`. |
312 | unsafe { |
313 | let new_len = unchecked_sub(self.end, self.start); |
314 | ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str |
315 | } |
316 | } |
317 | #[inline ] |
318 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
319 | let slice = slice as *mut [u8]; |
320 | |
321 | assert_unsafe_precondition!( |
322 | check_library_ub, |
323 | "str::get_unchecked_mut requires that the range is within the string slice" , |
324 | ( |
325 | start: usize = self.start, |
326 | end: usize = self.end, |
327 | len: usize = slice.len() |
328 | ) => end >= start && end <= len, |
329 | ); |
330 | |
331 | // SAFETY: see comments for `get_unchecked`. |
332 | unsafe { |
333 | let new_len = unchecked_sub(self.end, self.start); |
334 | ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str |
335 | } |
336 | } |
337 | #[inline ] |
338 | fn index(self, slice: &str) -> &Self::Output { |
339 | let (start, end) = (self.start, self.end); |
340 | match self.get(slice) { |
341 | Some(s) => s, |
342 | None => super::slice_error_fail(slice, start, end), |
343 | } |
344 | } |
345 | #[inline ] |
346 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
347 | // is_char_boundary checks that the index is in [0, .len()] |
348 | // cannot reuse `get` as above, because of NLL trouble |
349 | if self.start <= self.end |
350 | && slice.is_char_boundary(self.start) |
351 | && slice.is_char_boundary(self.end) |
352 | { |
353 | // SAFETY: just checked that `start` and `end` are on a char boundary, |
354 | // and we are passing in a safe reference, so the return value will also be one. |
355 | unsafe { &mut *self.get_unchecked_mut(slice) } |
356 | } else { |
357 | super::slice_error_fail(slice, self.start, self.end) |
358 | } |
359 | } |
360 | } |
361 | |
362 | /// Implements substring slicing for arbitrary bounds. |
363 | /// |
364 | /// Returns a slice of the given string bounded by the byte indices |
365 | /// provided by each bound. |
366 | /// |
367 | /// This operation is *O*(1). |
368 | /// |
369 | /// # Panics |
370 | /// |
371 | /// Panics if `begin` or `end` (if it exists and once adjusted for |
372 | /// inclusion/exclusion) does not point to the starting byte offset of |
373 | /// a character (as defined by `is_char_boundary`), if `begin > end`, or if |
374 | /// `end > len`. |
375 | #[stable (feature = "slice_index_str_with_ops_bound_pair" , since = "1.73.0" )] |
376 | unsafe impl SliceIndex<str> for (ops::Bound<usize>, ops::Bound<usize>) { |
377 | type Output = str; |
378 | |
379 | #[inline ] |
380 | fn get(self, slice: &str) -> Option<&str> { |
381 | crate::slice::index::into_range(slice.len(), self)?.get(slice) |
382 | } |
383 | |
384 | #[inline ] |
385 | fn get_mut(self, slice: &mut str) -> Option<&mut str> { |
386 | crate::slice::index::into_range(slice.len(), self)?.get_mut(slice) |
387 | } |
388 | |
389 | #[inline ] |
390 | unsafe fn get_unchecked(self, slice: *const str) -> *const str { |
391 | let len = (slice as *const [u8]).len(); |
392 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
393 | unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked(slice) } |
394 | } |
395 | |
396 | #[inline ] |
397 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut str { |
398 | let len = (slice as *mut [u8]).len(); |
399 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
400 | unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked_mut(slice) } |
401 | } |
402 | |
403 | #[inline ] |
404 | fn index(self, slice: &str) -> &str { |
405 | crate::slice::index::into_slice_range(slice.len(), self).index(slice) |
406 | } |
407 | |
408 | #[inline ] |
409 | fn index_mut(self, slice: &mut str) -> &mut str { |
410 | crate::slice::index::into_slice_range(slice.len(), self).index_mut(slice) |
411 | } |
412 | } |
413 | |
414 | /// Implements substring slicing with syntax `&self[.. end]` or `&mut |
415 | /// self[.. end]`. |
416 | /// |
417 | /// Returns a slice of the given string from the byte range \[0, `end`). |
418 | /// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`. |
419 | /// |
420 | /// This operation is *O*(1). |
421 | /// |
422 | /// Prior to 1.20.0, these indexing operations were still supported by |
423 | /// direct implementation of `Index` and `IndexMut`. |
424 | /// |
425 | /// # Panics |
426 | /// |
427 | /// Panics if `end` does not point to the starting byte offset of a |
428 | /// character (as defined by `is_char_boundary`), or if `end > len`. |
429 | #[stable (feature = "str_checked_slicing" , since = "1.20.0" )] |
430 | unsafe impl SliceIndex<str> for ops::RangeTo<usize> { |
431 | type Output = str; |
432 | #[inline ] |
433 | fn get(self, slice: &str) -> Option<&Self::Output> { |
434 | if slice.is_char_boundary(self.end) { |
435 | // SAFETY: just checked that `end` is on a char boundary, |
436 | // and we are passing in a safe reference, so the return value will also be one. |
437 | Some(unsafe { &*self.get_unchecked(slice) }) |
438 | } else { |
439 | None |
440 | } |
441 | } |
442 | #[inline ] |
443 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
444 | if slice.is_char_boundary(self.end) { |
445 | // SAFETY: just checked that `end` is on a char boundary, |
446 | // and we are passing in a safe reference, so the return value will also be one. |
447 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
448 | } else { |
449 | None |
450 | } |
451 | } |
452 | #[inline ] |
453 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
454 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
455 | unsafe { (0..self.end).get_unchecked(slice) } |
456 | } |
457 | #[inline ] |
458 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
459 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
460 | unsafe { (0..self.end).get_unchecked_mut(slice) } |
461 | } |
462 | #[inline ] |
463 | fn index(self, slice: &str) -> &Self::Output { |
464 | let end = self.end; |
465 | match self.get(slice) { |
466 | Some(s) => s, |
467 | None => super::slice_error_fail(slice, 0, end), |
468 | } |
469 | } |
470 | #[inline ] |
471 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
472 | if slice.is_char_boundary(self.end) { |
473 | // SAFETY: just checked that `end` is on a char boundary, |
474 | // and we are passing in a safe reference, so the return value will also be one. |
475 | unsafe { &mut *self.get_unchecked_mut(slice) } |
476 | } else { |
477 | super::slice_error_fail(slice, 0, self.end) |
478 | } |
479 | } |
480 | } |
481 | |
482 | /// Implements substring slicing with syntax `&self[begin ..]` or `&mut |
483 | /// self[begin ..]`. |
484 | /// |
485 | /// Returns a slice of the given string from the byte range \[`begin`, `len`). |
486 | /// Equivalent to `&self[begin .. len]` or `&mut self[begin .. len]`. |
487 | /// |
488 | /// This operation is *O*(1). |
489 | /// |
490 | /// Prior to 1.20.0, these indexing operations were still supported by |
491 | /// direct implementation of `Index` and `IndexMut`. |
492 | /// |
493 | /// # Panics |
494 | /// |
495 | /// Panics if `begin` does not point to the starting byte offset of |
496 | /// a character (as defined by `is_char_boundary`), or if `begin > len`. |
497 | #[stable (feature = "str_checked_slicing" , since = "1.20.0" )] |
498 | unsafe impl SliceIndex<str> for ops::RangeFrom<usize> { |
499 | type Output = str; |
500 | #[inline ] |
501 | fn get(self, slice: &str) -> Option<&Self::Output> { |
502 | if slice.is_char_boundary(self.start) { |
503 | // SAFETY: just checked that `start` is on a char boundary, |
504 | // and we are passing in a safe reference, so the return value will also be one. |
505 | Some(unsafe { &*self.get_unchecked(slice) }) |
506 | } else { |
507 | None |
508 | } |
509 | } |
510 | #[inline ] |
511 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
512 | if slice.is_char_boundary(self.start) { |
513 | // SAFETY: just checked that `start` is on a char boundary, |
514 | // and we are passing in a safe reference, so the return value will also be one. |
515 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
516 | } else { |
517 | None |
518 | } |
519 | } |
520 | #[inline ] |
521 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
522 | let len = (slice as *const [u8]).len(); |
523 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
524 | unsafe { (self.start..len).get_unchecked(slice) } |
525 | } |
526 | #[inline ] |
527 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
528 | let len = (slice as *mut [u8]).len(); |
529 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
530 | unsafe { (self.start..len).get_unchecked_mut(slice) } |
531 | } |
532 | #[inline ] |
533 | fn index(self, slice: &str) -> &Self::Output { |
534 | let (start, end) = (self.start, slice.len()); |
535 | match self.get(slice) { |
536 | Some(s) => s, |
537 | None => super::slice_error_fail(slice, start, end), |
538 | } |
539 | } |
540 | #[inline ] |
541 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
542 | if slice.is_char_boundary(self.start) { |
543 | // SAFETY: just checked that `start` is on a char boundary, |
544 | // and we are passing in a safe reference, so the return value will also be one. |
545 | unsafe { &mut *self.get_unchecked_mut(slice) } |
546 | } else { |
547 | super::slice_error_fail(slice, self.start, slice.len()) |
548 | } |
549 | } |
550 | } |
551 | |
552 | #[unstable (feature = "new_range_api" , issue = "125687" )] |
553 | unsafe impl SliceIndex<str> for range::RangeFrom<usize> { |
554 | type Output = str; |
555 | #[inline ] |
556 | fn get(self, slice: &str) -> Option<&Self::Output> { |
557 | if slice.is_char_boundary(self.start) { |
558 | // SAFETY: just checked that `start` is on a char boundary, |
559 | // and we are passing in a safe reference, so the return value will also be one. |
560 | Some(unsafe { &*self.get_unchecked(slice) }) |
561 | } else { |
562 | None |
563 | } |
564 | } |
565 | #[inline ] |
566 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
567 | if slice.is_char_boundary(self.start) { |
568 | // SAFETY: just checked that `start` is on a char boundary, |
569 | // and we are passing in a safe reference, so the return value will also be one. |
570 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
571 | } else { |
572 | None |
573 | } |
574 | } |
575 | #[inline ] |
576 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
577 | let len = (slice as *const [u8]).len(); |
578 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
579 | unsafe { (self.start..len).get_unchecked(slice) } |
580 | } |
581 | #[inline ] |
582 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
583 | let len = (slice as *mut [u8]).len(); |
584 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
585 | unsafe { (self.start..len).get_unchecked_mut(slice) } |
586 | } |
587 | #[inline ] |
588 | fn index(self, slice: &str) -> &Self::Output { |
589 | let (start, end) = (self.start, slice.len()); |
590 | match self.get(slice) { |
591 | Some(s) => s, |
592 | None => super::slice_error_fail(slice, start, end), |
593 | } |
594 | } |
595 | #[inline ] |
596 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
597 | if slice.is_char_boundary(self.start) { |
598 | // SAFETY: just checked that `start` is on a char boundary, |
599 | // and we are passing in a safe reference, so the return value will also be one. |
600 | unsafe { &mut *self.get_unchecked_mut(slice) } |
601 | } else { |
602 | super::slice_error_fail(slice, self.start, slice.len()) |
603 | } |
604 | } |
605 | } |
606 | |
607 | /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut |
608 | /// self[begin ..= end]`. |
609 | /// |
610 | /// Returns a slice of the given string from the byte range |
611 | /// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut |
612 | /// self[begin .. end + 1]`, except if `end` has the maximum value for |
613 | /// `usize`. |
614 | /// |
615 | /// This operation is *O*(1). |
616 | /// |
617 | /// # Panics |
618 | /// |
619 | /// Panics if `begin` does not point to the starting byte offset of |
620 | /// a character (as defined by `is_char_boundary`), if `end` does not point |
621 | /// to the ending byte offset of a character (`end + 1` is either a starting |
622 | /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. |
623 | #[stable (feature = "inclusive_range" , since = "1.26.0" )] |
624 | unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> { |
625 | type Output = str; |
626 | #[inline ] |
627 | fn get(self, slice: &str) -> Option<&Self::Output> { |
628 | if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) } |
629 | } |
630 | #[inline ] |
631 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
632 | if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } |
633 | } |
634 | #[inline ] |
635 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
636 | // SAFETY: the caller must uphold the safety contract for `get_unchecked`. |
637 | unsafe { self.into_slice_range().get_unchecked(slice) } |
638 | } |
639 | #[inline ] |
640 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
641 | // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. |
642 | unsafe { self.into_slice_range().get_unchecked_mut(slice) } |
643 | } |
644 | #[inline ] |
645 | fn index(self, slice: &str) -> &Self::Output { |
646 | if *self.end() == usize::MAX { |
647 | str_index_overflow_fail(); |
648 | } |
649 | self.into_slice_range().index(slice) |
650 | } |
651 | #[inline ] |
652 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
653 | if *self.end() == usize::MAX { |
654 | str_index_overflow_fail(); |
655 | } |
656 | self.into_slice_range().index_mut(slice) |
657 | } |
658 | } |
659 | |
660 | #[unstable (feature = "new_range_api" , issue = "125687" )] |
661 | unsafe impl SliceIndex<str> for range::RangeInclusive<usize> { |
662 | type Output = str; |
663 | #[inline ] |
664 | fn get(self, slice: &str) -> Option<&Self::Output> { |
665 | if self.end == usize::MAX { None } else { self.into_slice_range().get(slice) } |
666 | } |
667 | #[inline ] |
668 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
669 | if self.end == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } |
670 | } |
671 | #[inline ] |
672 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
673 | // SAFETY: the caller must uphold the safety contract for `get_unchecked`. |
674 | unsafe { self.into_slice_range().get_unchecked(slice) } |
675 | } |
676 | #[inline ] |
677 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
678 | // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. |
679 | unsafe { self.into_slice_range().get_unchecked_mut(slice) } |
680 | } |
681 | #[inline ] |
682 | fn index(self, slice: &str) -> &Self::Output { |
683 | if self.end == usize::MAX { |
684 | str_index_overflow_fail(); |
685 | } |
686 | self.into_slice_range().index(slice) |
687 | } |
688 | #[inline ] |
689 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
690 | if self.end == usize::MAX { |
691 | str_index_overflow_fail(); |
692 | } |
693 | self.into_slice_range().index_mut(slice) |
694 | } |
695 | } |
696 | |
697 | /// Implements substring slicing with syntax `&self[..= end]` or `&mut |
698 | /// self[..= end]`. |
699 | /// |
700 | /// Returns a slice of the given string from the byte range \[0, `end`\]. |
701 | /// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum |
702 | /// value for `usize`. |
703 | /// |
704 | /// This operation is *O*(1). |
705 | /// |
706 | /// # Panics |
707 | /// |
708 | /// Panics if `end` does not point to the ending byte offset of a character |
709 | /// (`end + 1` is either a starting byte offset as defined by |
710 | /// `is_char_boundary`, or equal to `len`), or if `end >= len`. |
711 | #[stable (feature = "inclusive_range" , since = "1.26.0" )] |
712 | unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> { |
713 | type Output = str; |
714 | #[inline ] |
715 | fn get(self, slice: &str) -> Option<&Self::Output> { |
716 | (0..=self.end).get(slice) |
717 | } |
718 | #[inline ] |
719 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
720 | (0..=self.end).get_mut(slice) |
721 | } |
722 | #[inline ] |
723 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
724 | // SAFETY: the caller must uphold the safety contract for `get_unchecked`. |
725 | unsafe { (0..=self.end).get_unchecked(slice) } |
726 | } |
727 | #[inline ] |
728 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
729 | // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. |
730 | unsafe { (0..=self.end).get_unchecked_mut(slice) } |
731 | } |
732 | #[inline ] |
733 | fn index(self, slice: &str) -> &Self::Output { |
734 | (0..=self.end).index(slice) |
735 | } |
736 | #[inline ] |
737 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
738 | (0..=self.end).index_mut(slice) |
739 | } |
740 | } |
741 | |
742 | /// Parse a value from a string |
743 | /// |
744 | /// `FromStr`'s [`from_str`] method is often used implicitly, through |
745 | /// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples. |
746 | /// |
747 | /// [`from_str`]: FromStr::from_str |
748 | /// [`parse`]: str::parse |
749 | /// |
750 | /// `FromStr` does not have a lifetime parameter, and so you can only parse types |
751 | /// that do not contain a lifetime parameter themselves. In other words, you can |
752 | /// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that |
753 | /// contains an `i32`, but not one that contains an `&i32`. |
754 | /// |
755 | /// # Examples |
756 | /// |
757 | /// Basic implementation of `FromStr` on an example `Point` type: |
758 | /// |
759 | /// ``` |
760 | /// use std::str::FromStr; |
761 | /// |
762 | /// #[derive(Debug, PartialEq)] |
763 | /// struct Point { |
764 | /// x: i32, |
765 | /// y: i32 |
766 | /// } |
767 | /// |
768 | /// #[derive(Debug, PartialEq, Eq)] |
769 | /// struct ParsePointError; |
770 | /// |
771 | /// impl FromStr for Point { |
772 | /// type Err = ParsePointError; |
773 | /// |
774 | /// fn from_str(s: &str) -> Result<Self, Self::Err> { |
775 | /// let (x, y) = s |
776 | /// .strip_prefix('(' ) |
777 | /// .and_then(|s| s.strip_suffix(')' )) |
778 | /// .and_then(|s| s.split_once(',' )) |
779 | /// .ok_or(ParsePointError)?; |
780 | /// |
781 | /// let x_fromstr = x.parse::<i32>().map_err(|_| ParsePointError)?; |
782 | /// let y_fromstr = y.parse::<i32>().map_err(|_| ParsePointError)?; |
783 | /// |
784 | /// Ok(Point { x: x_fromstr, y: y_fromstr }) |
785 | /// } |
786 | /// } |
787 | /// |
788 | /// let expected = Ok(Point { x: 1, y: 2 }); |
789 | /// // Explicit call |
790 | /// assert_eq!(Point::from_str("(1,2)" ), expected); |
791 | /// // Implicit calls, through parse |
792 | /// assert_eq!("(1,2)" .parse(), expected); |
793 | /// assert_eq!("(1,2)" .parse::<Point>(), expected); |
794 | /// // Invalid input string |
795 | /// assert!(Point::from_str("(1 2)" ).is_err()); |
796 | /// ``` |
797 | #[stable (feature = "rust1" , since = "1.0.0" )] |
798 | pub trait FromStr: Sized { |
799 | /// The associated error which can be returned from parsing. |
800 | #[stable (feature = "rust1" , since = "1.0.0" )] |
801 | type Err; |
802 | |
803 | /// Parses a string `s` to return a value of this type. |
804 | /// |
805 | /// If parsing succeeds, return the value inside [`Ok`], otherwise |
806 | /// when the string is ill-formatted return an error specific to the |
807 | /// inside [`Err`]. The error type is specific to the implementation of the trait. |
808 | /// |
809 | /// # Examples |
810 | /// |
811 | /// Basic usage with [`i32`], a type that implements `FromStr`: |
812 | /// |
813 | /// ``` |
814 | /// use std::str::FromStr; |
815 | /// |
816 | /// let s = "5" ; |
817 | /// let x = i32::from_str(s).unwrap(); |
818 | /// |
819 | /// assert_eq!(5, x); |
820 | /// ``` |
821 | #[stable (feature = "rust1" , since = "1.0.0" )] |
822 | #[rustc_diagnostic_item = "from_str_method" ] |
823 | fn from_str(s: &str) -> Result<Self, Self::Err>; |
824 | } |
825 | |
826 | #[stable (feature = "rust1" , since = "1.0.0" )] |
827 | impl FromStr for bool { |
828 | type Err = ParseBoolError; |
829 | |
830 | /// Parse a `bool` from a string. |
831 | /// |
832 | /// The only accepted values are `"true"` and `"false"`. Any other input |
833 | /// will return an error. |
834 | /// |
835 | /// # Examples |
836 | /// |
837 | /// ``` |
838 | /// use std::str::FromStr; |
839 | /// |
840 | /// assert_eq!(FromStr::from_str("true" ), Ok(true)); |
841 | /// assert_eq!(FromStr::from_str("false" ), Ok(false)); |
842 | /// assert!(<bool as FromStr>::from_str("not even a boolean" ).is_err()); |
843 | /// ``` |
844 | /// |
845 | /// Note, in many cases, the `.parse()` method on `str` is more proper. |
846 | /// |
847 | /// ``` |
848 | /// assert_eq!("true" .parse(), Ok(true)); |
849 | /// assert_eq!("false" .parse(), Ok(false)); |
850 | /// assert!("not even a boolean" .parse::<bool>().is_err()); |
851 | /// ``` |
852 | #[inline ] |
853 | fn from_str(s: &str) -> Result<bool, ParseBoolError> { |
854 | match s { |
855 | "true" => Ok(true), |
856 | "false" => Ok(false), |
857 | _ => Err(ParseBoolError), |
858 | } |
859 | } |
860 | } |
861 | |