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