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