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