core/str/
traits.rs

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