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