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