Skip to main content

core/str/
traits.rs

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