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