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