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