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