Skip to main content

core/str/
traits.rs

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