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