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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy