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