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