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