core/str/
traits.rs

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