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