Skip to main content

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