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;
7#[cfg(not(feature = "ferrocene_certified"))]
8use crate::intrinsics::unchecked_sub;
9#[cfg(not(feature = "ferrocene_certified"))]
10use crate::slice::SliceIndex;
11#[cfg(not(feature = "ferrocene_certified"))]
12use crate::ub_checks::assert_unsafe_precondition;
13#[cfg(not(feature = "ferrocene_certified"))]
14use crate::{ops, ptr, range};
15
16/// Implements ordering of strings.
17///
18/// Strings are ordered  [lexicographically](Ord#lexicographical-comparison) by their byte values. This orders Unicode code
19/// points based on their positions in the code charts. This is not necessarily the same as
20/// "alphabetical" order, which varies by language and locale. Sorting strings according to
21/// culturally-accepted standards requires locale-specific data that is outside the scope of
22/// the `str` type.
23#[stable(feature = "rust1", since = "1.0.0")]
24#[cfg(not(feature = "ferrocene_certified"))]
25impl Ord for str {
26    #[inline]
27    fn cmp(&self, other: &str) -> Ordering {
28        self.as_bytes().cmp(other.as_bytes())
29    }
30}
31
32#[stable(feature = "rust1", since = "1.0.0")]
33#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
34#[cfg(not(feature = "ferrocene_certified"))]
35impl const PartialEq for str {
36    #[inline]
37    fn eq(&self, other: &str) -> bool {
38        self.as_bytes() == other.as_bytes()
39    }
40}
41
42#[stable(feature = "rust1", since = "1.0.0")]
43#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
44#[cfg(not(feature = "ferrocene_certified"))]
45impl const Eq for str {}
46
47/// Implements comparison operations on strings.
48///
49/// Strings are compared [lexicographically](Ord#lexicographical-comparison) by their byte values. This compares Unicode code
50/// points based on their positions in the code charts. This is not necessarily the same as
51/// "alphabetical" order, which varies by language and locale. Comparing strings according to
52/// culturally-accepted standards requires locale-specific data that is outside the scope of
53/// the `str` type.
54#[stable(feature = "rust1", since = "1.0.0")]
55#[cfg(not(feature = "ferrocene_certified"))]
56impl PartialOrd for str {
57    #[inline]
58    fn partial_cmp(&self, other: &str) -> Option<Ordering> {
59        Some(self.cmp(other))
60    }
61}
62
63#[stable(feature = "rust1", since = "1.0.0")]
64#[rustc_const_unstable(feature = "const_index", issue = "143775")]
65#[cfg(not(feature = "ferrocene_certified"))]
66impl<I> const ops::Index<I> for str
67where
68    I: [const] SliceIndex<str>,
69{
70    type Output = I::Output;
71
72    #[inline]
73    fn index(&self, index: I) -> &I::Output {
74        index.index(self)
75    }
76}
77
78#[stable(feature = "rust1", since = "1.0.0")]
79#[rustc_const_unstable(feature = "const_index", issue = "143775")]
80#[cfg(not(feature = "ferrocene_certified"))]
81impl<I> const ops::IndexMut<I> for str
82where
83    I: [const] SliceIndex<str>,
84{
85    #[inline]
86    fn index_mut(&mut self, index: I) -> &mut I::Output {
87        index.index_mut(self)
88    }
89}
90
91#[inline(never)]
92#[cold]
93#[track_caller]
94#[cfg(not(feature = "ferrocene_certified"))]
95const fn str_index_overflow_fail() -> ! {
96    panic!("attempted to index str up to maximum usize");
97}
98
99/// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
100///
101/// Returns a slice of the whole string, i.e., returns `&self` or `&mut
102/// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike
103/// other indexing operations, this can never panic.
104///
105/// This operation is *O*(1).
106///
107/// Prior to 1.20.0, these indexing operations were still supported by
108/// direct implementation of `Index` and `IndexMut`.
109///
110/// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
111#[stable(feature = "str_checked_slicing", since = "1.20.0")]
112#[rustc_const_unstable(feature = "const_index", issue = "143775")]
113#[cfg(not(feature = "ferrocene_certified"))]
114unsafe impl const SliceIndex<str> for ops::RangeFull {
115    type Output = str;
116    #[inline]
117    fn get(self, slice: &str) -> Option<&Self::Output> {
118        Some(slice)
119    }
120    #[inline]
121    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
122        Some(slice)
123    }
124    #[inline]
125    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
126        slice
127    }
128    #[inline]
129    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
130        slice
131    }
132    #[inline]
133    fn index(self, slice: &str) -> &Self::Output {
134        slice
135    }
136    #[inline]
137    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
138        slice
139    }
140}
141
142/// Implements substring slicing with syntax `&self[begin .. end]` or `&mut
143/// self[begin .. end]`.
144///
145/// Returns a slice of the given string from the byte range
146/// [`begin`, `end`).
147///
148/// This operation is *O*(1).
149///
150/// Prior to 1.20.0, these indexing operations were still supported by
151/// direct implementation of `Index` and `IndexMut`.
152///
153/// # Panics
154///
155/// Panics if `begin` or `end` does not point to the starting byte offset of
156/// a character (as defined by `is_char_boundary`), if `begin > end`, or if
157/// `end > len`.
158///
159/// # Examples
160///
161/// ```
162/// let s = "Löwe 老虎 Léopard";
163/// assert_eq!(&s[0 .. 1], "L");
164///
165/// assert_eq!(&s[1 .. 9], "öwe 老");
166///
167/// // these will panic:
168/// // byte 2 lies within `ö`:
169/// // &s[2 ..3];
170///
171/// // byte 8 lies within `老`
172/// // &s[1 .. 8];
173///
174/// // byte 100 is outside the string
175/// // &s[3 .. 100];
176/// ```
177#[stable(feature = "str_checked_slicing", since = "1.20.0")]
178#[rustc_const_unstable(feature = "const_index", issue = "143775")]
179#[cfg(not(feature = "ferrocene_certified"))]
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")]
459#[cfg(not(feature = "ferrocene_certified"))]
460unsafe impl const SliceIndex<str> for ops::RangeTo<usize> {
461    type Output = str;
462    #[inline]
463    fn get(self, slice: &str) -> Option<&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            Some(unsafe { &*self.get_unchecked(slice) })
468        } else {
469            None
470        }
471    }
472    #[inline]
473    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
474        if slice.is_char_boundary(self.end) {
475            // SAFETY: just checked that `end` is on a char boundary,
476            // and we are passing in a safe reference, so the return value will also be one.
477            Some(unsafe { &mut *self.get_unchecked_mut(slice) })
478        } else {
479            None
480        }
481    }
482    #[inline]
483    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
484        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
485        unsafe { (0..self.end).get_unchecked(slice) }
486    }
487    #[inline]
488    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
489        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
490        unsafe { (0..self.end).get_unchecked_mut(slice) }
491    }
492    #[inline]
493    fn index(self, slice: &str) -> &Self::Output {
494        let end = self.end;
495        match self.get(slice) {
496            Some(s) => s,
497            None => super::slice_error_fail(slice, 0, end),
498        }
499    }
500    #[inline]
501    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
502        if slice.is_char_boundary(self.end) {
503            // SAFETY: just checked that `end` is on a char boundary,
504            // and we are passing in a safe reference, so the return value will also be one.
505            unsafe { &mut *self.get_unchecked_mut(slice) }
506        } else {
507            super::slice_error_fail(slice, 0, self.end)
508        }
509    }
510}
511
512/// Implements substring slicing with syntax `&self[begin ..]` or `&mut
513/// self[begin ..]`.
514///
515/// Returns a slice of the given string from the byte range \[`begin`, `len`).
516/// Equivalent to `&self[begin .. len]` or `&mut self[begin .. len]`.
517///
518/// This operation is *O*(1).
519///
520/// Prior to 1.20.0, these indexing operations were still supported by
521/// direct implementation of `Index` and `IndexMut`.
522///
523/// # Panics
524///
525/// Panics if `begin` does not point to the starting byte offset of
526/// a character (as defined by `is_char_boundary`), or if `begin > len`.
527#[stable(feature = "str_checked_slicing", since = "1.20.0")]
528#[rustc_const_unstable(feature = "const_index", issue = "143775")]
529#[cfg(not(feature = "ferrocene_certified"))]
530unsafe impl const SliceIndex<str> for ops::RangeFrom<usize> {
531    type Output = str;
532    #[inline]
533    fn get(self, slice: &str) -> Option<&Self::Output> {
534        if slice.is_char_boundary(self.start) {
535            // SAFETY: just checked that `start` is on a char boundary,
536            // and we are passing in a safe reference, so the return value will also be one.
537            Some(unsafe { &*self.get_unchecked(slice) })
538        } else {
539            None
540        }
541    }
542    #[inline]
543    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
544        if slice.is_char_boundary(self.start) {
545            // SAFETY: just checked that `start` is on a char boundary,
546            // and we are passing in a safe reference, so the return value will also be one.
547            Some(unsafe { &mut *self.get_unchecked_mut(slice) })
548        } else {
549            None
550        }
551    }
552    #[inline]
553    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
554        let len = (slice as *const [u8]).len();
555        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
556        unsafe { (self.start..len).get_unchecked(slice) }
557    }
558    #[inline]
559    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
560        let len = (slice as *mut [u8]).len();
561        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
562        unsafe { (self.start..len).get_unchecked_mut(slice) }
563    }
564    #[inline]
565    fn index(self, slice: &str) -> &Self::Output {
566        let (start, end) = (self.start, slice.len());
567        match self.get(slice) {
568            Some(s) => s,
569            None => super::slice_error_fail(slice, start, end),
570        }
571    }
572    #[inline]
573    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
574        if slice.is_char_boundary(self.start) {
575            // SAFETY: just checked that `start` is on a char boundary,
576            // and we are passing in a safe reference, so the return value will also be one.
577            unsafe { &mut *self.get_unchecked_mut(slice) }
578        } else {
579            super::slice_error_fail(slice, self.start, slice.len())
580        }
581    }
582}
583
584#[unstable(feature = "new_range_api", issue = "125687")]
585#[rustc_const_unstable(feature = "const_index", issue = "143775")]
586#[cfg(not(feature = "ferrocene_certified"))]
587unsafe impl const SliceIndex<str> for range::RangeFrom<usize> {
588    type Output = str;
589    #[inline]
590    fn get(self, slice: &str) -> Option<&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            Some(unsafe { &*self.get_unchecked(slice) })
595        } else {
596            None
597        }
598    }
599    #[inline]
600    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
601        if slice.is_char_boundary(self.start) {
602            // SAFETY: just checked that `start` is on a char boundary,
603            // and we are passing in a safe reference, so the return value will also be one.
604            Some(unsafe { &mut *self.get_unchecked_mut(slice) })
605        } else {
606            None
607        }
608    }
609    #[inline]
610    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
611        let len = (slice as *const [u8]).len();
612        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
613        unsafe { (self.start..len).get_unchecked(slice) }
614    }
615    #[inline]
616    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
617        let len = (slice as *mut [u8]).len();
618        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
619        unsafe { (self.start..len).get_unchecked_mut(slice) }
620    }
621    #[inline]
622    fn index(self, slice: &str) -> &Self::Output {
623        let (start, end) = (self.start, slice.len());
624        match self.get(slice) {
625            Some(s) => s,
626            None => super::slice_error_fail(slice, start, end),
627        }
628    }
629    #[inline]
630    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
631        if slice.is_char_boundary(self.start) {
632            // SAFETY: just checked that `start` is on a char boundary,
633            // and we are passing in a safe reference, so the return value will also be one.
634            unsafe { &mut *self.get_unchecked_mut(slice) }
635        } else {
636            super::slice_error_fail(slice, self.start, slice.len())
637        }
638    }
639}
640
641/// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut
642/// self[begin ..= end]`.
643///
644/// Returns a slice of the given string from the byte range
645/// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut
646/// self[begin .. end + 1]`, except if `end` has the maximum value for
647/// `usize`.
648///
649/// This operation is *O*(1).
650///
651/// # Panics
652///
653/// Panics if `begin` does not point to the starting byte offset of
654/// a character (as defined by `is_char_boundary`), if `end` does not point
655/// to the ending byte offset of a character (`end + 1` is either a starting
656/// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
657#[stable(feature = "inclusive_range", since = "1.26.0")]
658#[rustc_const_unstable(feature = "const_index", issue = "143775")]
659#[cfg(not(feature = "ferrocene_certified"))]
660unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> {
661    type Output = str;
662    #[inline]
663    fn get(self, slice: &str) -> Option<&Self::Output> {
664        if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
665    }
666    #[inline]
667    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
668        if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
669    }
670    #[inline]
671    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
672        // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
673        unsafe { self.into_slice_range().get_unchecked(slice) }
674    }
675    #[inline]
676    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
677        // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
678        unsafe { self.into_slice_range().get_unchecked_mut(slice) }
679    }
680    #[inline]
681    fn index(self, slice: &str) -> &Self::Output {
682        if *self.end() == usize::MAX {
683            str_index_overflow_fail();
684        }
685        self.into_slice_range().index(slice)
686    }
687    #[inline]
688    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
689        if *self.end() == usize::MAX {
690            str_index_overflow_fail();
691        }
692        self.into_slice_range().index_mut(slice)
693    }
694}
695
696#[unstable(feature = "new_range_api", issue = "125687")]
697#[rustc_const_unstable(feature = "const_index", issue = "143775")]
698#[cfg(not(feature = "ferrocene_certified"))]
699unsafe impl const SliceIndex<str> for range::RangeInclusive<usize> {
700    type Output = str;
701    #[inline]
702    fn get(self, slice: &str) -> Option<&Self::Output> {
703        if self.last == usize::MAX { None } else { self.into_slice_range().get(slice) }
704    }
705    #[inline]
706    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
707        if self.last == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
708    }
709    #[inline]
710    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
711        // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
712        unsafe { self.into_slice_range().get_unchecked(slice) }
713    }
714    #[inline]
715    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
716        // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
717        unsafe { self.into_slice_range().get_unchecked_mut(slice) }
718    }
719    #[inline]
720    fn index(self, slice: &str) -> &Self::Output {
721        if self.last == usize::MAX {
722            str_index_overflow_fail();
723        }
724        self.into_slice_range().index(slice)
725    }
726    #[inline]
727    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
728        if self.last == usize::MAX {
729            str_index_overflow_fail();
730        }
731        self.into_slice_range().index_mut(slice)
732    }
733}
734
735/// Implements substring slicing with syntax `&self[..= end]` or `&mut
736/// self[..= end]`.
737///
738/// Returns a slice of the given string from the byte range \[0, `end`\].
739/// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum
740/// value for `usize`.
741///
742/// This operation is *O*(1).
743///
744/// # Panics
745///
746/// Panics if `end` does not point to the ending byte offset of a character
747/// (`end + 1` is either a starting byte offset as defined by
748/// `is_char_boundary`, or equal to `len`), or if `end >= len`.
749#[stable(feature = "inclusive_range", since = "1.26.0")]
750#[rustc_const_unstable(feature = "const_index", issue = "143775")]
751#[cfg(not(feature = "ferrocene_certified"))]
752unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
753    type Output = str;
754    #[inline]
755    fn get(self, slice: &str) -> Option<&Self::Output> {
756        (0..=self.end).get(slice)
757    }
758    #[inline]
759    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
760        (0..=self.end).get_mut(slice)
761    }
762    #[inline]
763    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
764        // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
765        unsafe { (0..=self.end).get_unchecked(slice) }
766    }
767    #[inline]
768    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
769        // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
770        unsafe { (0..=self.end).get_unchecked_mut(slice) }
771    }
772    #[inline]
773    fn index(self, slice: &str) -> &Self::Output {
774        (0..=self.end).index(slice)
775    }
776    #[inline]
777    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
778        (0..=self.end).index_mut(slice)
779    }
780}
781
782/// Parse a value from a string
783///
784/// `FromStr`'s [`from_str`] method is often used implicitly, through
785/// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
786///
787/// [`from_str`]: FromStr::from_str
788/// [`parse`]: str::parse
789///
790/// `FromStr` does not have a lifetime parameter, and so you can only parse types
791/// that do not contain a lifetime parameter themselves. In other words, you can
792/// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that
793/// contains an `i32`, but not one that contains an `&i32`.
794///
795/// # Input format and round-tripping
796///
797/// The input format expected by a type's `FromStr` implementation depends on the type. Check the
798/// type's documentation for the input formats it knows how to parse. Note that the input format of
799/// a type's `FromStr` implementation might not necessarily accept the output format of its
800/// `Display` implementation, and even if it does, the `Display` implementation may not be lossless
801/// so the round-trip may lose information.
802///
803/// However, if a type has a lossless `Display` implementation whose output is meant to be
804/// conveniently machine-parseable and not just meant for human consumption, then the type may wish
805/// to accept the same format in `FromStr`, and document that usage. Having both `Display` and
806/// `FromStr` implementations where the result of `Display` cannot be parsed with `FromStr` may
807/// surprise users.
808///
809/// # Examples
810///
811/// Basic implementation of `FromStr` on an example `Point` type:
812///
813/// ```
814/// use std::str::FromStr;
815///
816/// #[derive(Debug, PartialEq)]
817/// struct Point {
818///     x: i32,
819///     y: i32
820/// }
821///
822/// #[derive(Debug, PartialEq, Eq)]
823/// struct ParsePointError;
824///
825/// impl FromStr for Point {
826///     type Err = ParsePointError;
827///
828///     fn from_str(s: &str) -> Result<Self, Self::Err> {
829///         let (x, y) = s
830///             .strip_prefix('(')
831///             .and_then(|s| s.strip_suffix(')'))
832///             .and_then(|s| s.split_once(','))
833///             .ok_or(ParsePointError)?;
834///
835///         let x_fromstr = x.parse::<i32>().map_err(|_| ParsePointError)?;
836///         let y_fromstr = y.parse::<i32>().map_err(|_| ParsePointError)?;
837///
838///         Ok(Point { x: x_fromstr, y: y_fromstr })
839///     }
840/// }
841///
842/// let expected = Ok(Point { x: 1, y: 2 });
843/// // Explicit call
844/// assert_eq!(Point::from_str("(1,2)"), expected);
845/// // Implicit calls, through parse
846/// assert_eq!("(1,2)".parse(), expected);
847/// assert_eq!("(1,2)".parse::<Point>(), expected);
848/// // Invalid input string
849/// assert!(Point::from_str("(1 2)").is_err());
850/// ```
851#[stable(feature = "rust1", since = "1.0.0")]
852#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
853pub const trait FromStr: Sized {
854    /// The associated error which can be returned from parsing.
855    #[stable(feature = "rust1", since = "1.0.0")]
856    type Err;
857
858    /// Parses a string `s` to return a value of this type.
859    ///
860    /// If parsing succeeds, return the value inside [`Ok`], otherwise
861    /// when the string is ill-formatted return an error specific to the
862    /// inside [`Err`]. The error type is specific to the implementation of the trait.
863    ///
864    /// # Examples
865    ///
866    /// Basic usage with [`i32`], a type that implements `FromStr`:
867    ///
868    /// ```
869    /// use std::str::FromStr;
870    ///
871    /// let s = "5";
872    /// let x = i32::from_str(s).unwrap();
873    ///
874    /// assert_eq!(5, x);
875    /// ```
876    #[stable(feature = "rust1", since = "1.0.0")]
877    #[rustc_diagnostic_item = "from_str_method"]
878    fn from_str(s: &str) -> Result<Self, Self::Err>;
879}
880
881#[stable(feature = "rust1", since = "1.0.0")]
882#[cfg(not(feature = "ferrocene_certified"))]
883impl FromStr for bool {
884    type Err = ParseBoolError;
885
886    /// Parse a `bool` from a string.
887    ///
888    /// The only accepted values are `"true"` and `"false"`. Any other input
889    /// will return an error.
890    ///
891    /// # Examples
892    ///
893    /// ```
894    /// use std::str::FromStr;
895    ///
896    /// assert_eq!(FromStr::from_str("true"), Ok(true));
897    /// assert_eq!(FromStr::from_str("false"), Ok(false));
898    /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
899    /// ```
900    ///
901    /// Note, in many cases, the `.parse()` method on `str` is more proper.
902    ///
903    /// ```
904    /// assert_eq!("true".parse(), Ok(true));
905    /// assert_eq!("false".parse(), Ok(false));
906    /// assert!("not even a boolean".parse::<bool>().is_err());
907    /// ```
908    #[inline]
909    fn from_str(s: &str) -> Result<bool, ParseBoolError> {
910        match s {
911            "true" => Ok(true),
912            "false" => Ok(false),
913            _ => Err(ParseBoolError),
914        }
915    }
916}