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