1 //! Trait implementations for `str`.
3 use crate::cmp::Ordering;
6 use crate::slice::SliceIndex;
8 use super::ParseBoolError;
10 /// Implements ordering of strings.
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
17 #[stable(feature = "rust1", since = "1.0.0")]
20 fn cmp(&self, other: &str) -> Ordering {
21 self.as_bytes().cmp(other.as_bytes())
25 #[stable(feature = "rust1", since = "1.0.0")]
26 impl PartialEq for str {
28 fn eq(&self, other: &str) -> bool {
29 self.as_bytes() == other.as_bytes()
32 fn ne(&self, other: &str) -> bool {
37 #[stable(feature = "rust1", since = "1.0.0")]
40 /// Implements comparison operations on strings.
42 /// Strings are compared [lexicographically](Ord#lexicographical-comparison) by their byte values. This compares Unicode code
43 /// points based on their positions in the code charts. This is not necessarily the same as
44 /// "alphabetical" order, which varies by language and locale. Comparing strings according to
45 /// culturally-accepted standards requires locale-specific data that is outside the scope of
47 #[stable(feature = "rust1", since = "1.0.0")]
48 impl PartialOrd for str {
50 fn partial_cmp(&self, other: &str) -> Option<Ordering> {
55 #[stable(feature = "rust1", since = "1.0.0")]
56 impl<I> ops::Index<I> for str
60 type Output = I::Output;
63 fn index(&self, index: I) -> &I::Output {
68 #[stable(feature = "rust1", since = "1.0.0")]
69 impl<I> ops::IndexMut<I> for str
74 fn index_mut(&mut self, index: I) -> &mut I::Output {
82 fn str_index_overflow_fail() -> ! {
83 panic!("attempted to index str up to maximum usize");
86 /// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
88 /// Returns a slice of the whole string, i.e., returns `&self` or `&mut
89 /// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike
90 /// other indexing operations, this can never panic.
92 /// This operation is *O*(1).
94 /// Prior to 1.20.0, these indexing operations were still supported by
95 /// direct implementation of `Index` and `IndexMut`.
97 /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
98 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
99 unsafe impl SliceIndex<str> for ops::RangeFull {
102 fn get(self, slice: &str) -> Option<&Self::Output> {
106 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
110 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
114 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
118 fn index(self, slice: &str) -> &Self::Output {
122 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
127 /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut
128 /// self[begin .. end]`.
130 /// Returns a slice of the given string from the byte range
131 /// [`begin`, `end`).
133 /// This operation is *O*(1).
135 /// Prior to 1.20.0, these indexing operations were still supported by
136 /// direct implementation of `Index` and `IndexMut`.
140 /// Panics if `begin` or `end` does not point to the starting byte offset of
141 /// a character (as defined by `is_char_boundary`), if `begin > end`, or if
147 /// let s = "Löwe 老虎 Léopard";
148 /// assert_eq!(&s[0 .. 1], "L");
150 /// assert_eq!(&s[1 .. 9], "öwe 老");
152 /// // these will panic:
153 /// // byte 2 lies within `ö`:
156 /// // byte 8 lies within `老`
159 /// // byte 100 is outside the string
162 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
163 unsafe impl SliceIndex<str> for ops::Range<usize> {
166 fn get(self, slice: &str) -> Option<&Self::Output> {
167 if self.start <= self.end
168 && slice.is_char_boundary(self.start)
169 && slice.is_char_boundary(self.end)
171 // SAFETY: just checked that `start` and `end` are on a char boundary,
172 // and we are passing in a safe reference, so the return value will also be one.
173 // We also checked char boundaries, so this is valid UTF-8.
174 Some(unsafe { &*self.get_unchecked(slice) })
180 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
181 if self.start <= self.end
182 && slice.is_char_boundary(self.start)
183 && slice.is_char_boundary(self.end)
185 // SAFETY: just checked that `start` and `end` are on a char boundary.
186 // We know the pointer is unique because we got it from `slice`.
187 Some(unsafe { &mut *self.get_unchecked_mut(slice) })
193 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
194 let slice = slice as *const [u8];
195 // SAFETY: the caller guarantees that `self` is in bounds of `slice`
196 // which satisfies all the conditions for `add`.
197 let ptr = unsafe { slice.as_ptr().add(self.start) };
198 let len = self.end - self.start;
199 ptr::slice_from_raw_parts(ptr, len) as *const str
202 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
203 let slice = slice as *mut [u8];
204 // SAFETY: see comments for `get_unchecked`.
205 let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
206 let len = self.end - self.start;
207 ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
210 fn index(self, slice: &str) -> &Self::Output {
211 let (start, end) = (self.start, self.end);
212 match self.get(slice) {
214 None => super::slice_error_fail(slice, start, end),
218 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
219 // is_char_boundary checks that the index is in [0, .len()]
220 // cannot reuse `get` as above, because of NLL trouble
221 if self.start <= self.end
222 && slice.is_char_boundary(self.start)
223 && slice.is_char_boundary(self.end)
225 // SAFETY: just checked that `start` and `end` are on a char boundary,
226 // and we are passing in a safe reference, so the return value will also be one.
227 unsafe { &mut *self.get_unchecked_mut(slice) }
229 super::slice_error_fail(slice, self.start, self.end)
234 /// Implements substring slicing with syntax `&self[.. end]` or `&mut
237 /// Returns a slice of the given string from the byte range \[0, `end`).
238 /// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`.
240 /// This operation is *O*(1).
242 /// Prior to 1.20.0, these indexing operations were still supported by
243 /// direct implementation of `Index` and `IndexMut`.
247 /// Panics if `end` does not point to the starting byte offset of a
248 /// character (as defined by `is_char_boundary`), or if `end > len`.
249 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
250 unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
253 fn get(self, slice: &str) -> Option<&Self::Output> {
254 if slice.is_char_boundary(self.end) {
255 // SAFETY: just checked that `end` is on a char boundary,
256 // and we are passing in a safe reference, so the return value will also be one.
257 Some(unsafe { &*self.get_unchecked(slice) })
263 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
264 if slice.is_char_boundary(self.end) {
265 // SAFETY: just checked that `end` is on a char boundary,
266 // and we are passing in a safe reference, so the return value will also be one.
267 Some(unsafe { &mut *self.get_unchecked_mut(slice) })
273 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
274 let slice = slice as *const [u8];
275 let ptr = slice.as_ptr();
276 ptr::slice_from_raw_parts(ptr, self.end) as *const str
279 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
280 let slice = slice as *mut [u8];
281 let ptr = slice.as_mut_ptr();
282 ptr::slice_from_raw_parts_mut(ptr, self.end) as *mut str
285 fn index(self, slice: &str) -> &Self::Output {
287 match self.get(slice) {
289 None => super::slice_error_fail(slice, 0, end),
293 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
294 if slice.is_char_boundary(self.end) {
295 // SAFETY: just checked that `end` is on a char boundary,
296 // and we are passing in a safe reference, so the return value will also be one.
297 unsafe { &mut *self.get_unchecked_mut(slice) }
299 super::slice_error_fail(slice, 0, self.end)
304 /// Implements substring slicing with syntax `&self[begin ..]` or `&mut
307 /// Returns a slice of the given string from the byte range \[`begin`, `len`).
308 /// Equivalent to `&self[begin .. len]` or `&mut self[begin .. len]`.
310 /// This operation is *O*(1).
312 /// Prior to 1.20.0, these indexing operations were still supported by
313 /// direct implementation of `Index` and `IndexMut`.
317 /// Panics if `begin` does not point to the starting byte offset of
318 /// a character (as defined by `is_char_boundary`), or if `begin > len`.
319 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
320 unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
323 fn get(self, slice: &str) -> Option<&Self::Output> {
324 if slice.is_char_boundary(self.start) {
325 // SAFETY: just checked that `start` is on a char boundary,
326 // and we are passing in a safe reference, so the return value will also be one.
327 Some(unsafe { &*self.get_unchecked(slice) })
333 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
334 if slice.is_char_boundary(self.start) {
335 // SAFETY: just checked that `start` is on a char boundary,
336 // and we are passing in a safe reference, so the return value will also be one.
337 Some(unsafe { &mut *self.get_unchecked_mut(slice) })
343 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
344 let slice = slice as *const [u8];
345 // SAFETY: the caller guarantees that `self` is in bounds of `slice`
346 // which satisfies all the conditions for `add`.
347 let ptr = unsafe { slice.as_ptr().add(self.start) };
348 let len = slice.len() - self.start;
349 ptr::slice_from_raw_parts(ptr, len) as *const str
352 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
353 let slice = slice as *mut [u8];
354 // SAFETY: identical to `get_unchecked`.
355 let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
356 let len = slice.len() - self.start;
357 ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
360 fn index(self, slice: &str) -> &Self::Output {
361 let (start, end) = (self.start, slice.len());
362 match self.get(slice) {
364 None => super::slice_error_fail(slice, start, end),
368 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
369 if slice.is_char_boundary(self.start) {
370 // SAFETY: just checked that `start` is on a char boundary,
371 // and we are passing in a safe reference, so the return value will also be one.
372 unsafe { &mut *self.get_unchecked_mut(slice) }
374 super::slice_error_fail(slice, self.start, slice.len())
379 /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut
380 /// self[begin ..= end]`.
382 /// Returns a slice of the given string from the byte range
383 /// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut
384 /// self[begin .. end + 1]`, except if `end` has the maximum value for
387 /// This operation is *O*(1).
391 /// Panics if `begin` does not point to the starting byte offset of
392 /// a character (as defined by `is_char_boundary`), if `end` does not point
393 /// to the ending byte offset of a character (`end + 1` is either a starting
394 /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
395 #[stable(feature = "inclusive_range", since = "1.26.0")]
396 unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
399 fn get(self, slice: &str) -> Option<&Self::Output> {
400 if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
403 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
404 if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
407 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
408 // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
409 unsafe { self.into_slice_range().get_unchecked(slice) }
412 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
413 // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
414 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
417 fn index(self, slice: &str) -> &Self::Output {
418 if *self.end() == usize::MAX {
419 str_index_overflow_fail();
421 self.into_slice_range().index(slice)
424 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
425 if *self.end() == usize::MAX {
426 str_index_overflow_fail();
428 self.into_slice_range().index_mut(slice)
432 /// Implements substring slicing with syntax `&self[..= end]` or `&mut
435 /// Returns a slice of the given string from the byte range \[0, `end`\].
436 /// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum
437 /// value for `usize`.
439 /// This operation is *O*(1).
443 /// Panics if `end` does not point to the ending byte offset of a character
444 /// (`end + 1` is either a starting byte offset as defined by
445 /// `is_char_boundary`, or equal to `len`), or if `end >= len`.
446 #[stable(feature = "inclusive_range", since = "1.26.0")]
447 unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> {
450 fn get(self, slice: &str) -> Option<&Self::Output> {
451 if self.end == usize::MAX { None } else { (..self.end + 1).get(slice) }
454 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
455 if self.end == usize::MAX { None } else { (..self.end + 1).get_mut(slice) }
458 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
459 // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
460 unsafe { (..self.end + 1).get_unchecked(slice) }
463 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
464 // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
465 unsafe { (..self.end + 1).get_unchecked_mut(slice) }
468 fn index(self, slice: &str) -> &Self::Output {
469 if self.end == usize::MAX {
470 str_index_overflow_fail();
472 (..self.end + 1).index(slice)
475 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
476 if self.end == usize::MAX {
477 str_index_overflow_fail();
479 (..self.end + 1).index_mut(slice)
483 /// Parse a value from a string
485 /// `FromStr`'s [`from_str`] method is often used implicitly, through
486 /// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
488 /// [`from_str`]: FromStr::from_str
489 /// [`parse`]: str::parse
491 /// `FromStr` does not have a lifetime parameter, and so you can only parse types
492 /// that do not contain a lifetime parameter themselves. In other words, you can
493 /// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that
494 /// contains an `i32`, but not one that contains an `&i32`.
498 /// Basic implementation of `FromStr` on an example `Point` type:
501 /// use std::str::FromStr;
502 /// use std::num::ParseIntError;
504 /// #[derive(Debug, PartialEq)]
510 /// impl FromStr for Point {
511 /// type Err = ParseIntError;
513 /// fn from_str(s: &str) -> Result<Self, Self::Err> {
514 /// let coords: Vec<&str> = s.trim_matches(|p| p == '(' || p == ')' )
518 /// let x_fromstr = coords[0].parse::<i32>()?;
519 /// let y_fromstr = coords[1].parse::<i32>()?;
521 /// Ok(Point { x: x_fromstr, y: y_fromstr })
525 /// let p = Point::from_str("(1,2)");
526 /// assert_eq!(p.unwrap(), Point{ x: 1, y: 2} )
528 #[stable(feature = "rust1", since = "1.0.0")]
529 pub trait FromStr: Sized {
530 /// The associated error which can be returned from parsing.
531 #[stable(feature = "rust1", since = "1.0.0")]
534 /// Parses a string `s` to return a value of this type.
536 /// If parsing succeeds, return the value inside [`Ok`], otherwise
537 /// when the string is ill-formatted return an error specific to the
538 /// inside [`Err`]. The error type is specific to the implementation of the trait.
542 /// Basic usage with [`i32`], a type that implements `FromStr`:
545 /// use std::str::FromStr;
548 /// let x = i32::from_str(s).unwrap();
550 /// assert_eq!(5, x);
552 #[stable(feature = "rust1", since = "1.0.0")]
553 fn from_str(s: &str) -> Result<Self, Self::Err>;
556 #[stable(feature = "rust1", since = "1.0.0")]
557 impl FromStr for bool {
558 type Err = ParseBoolError;
560 /// Parse a `bool` from a string.
562 /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not
563 /// actually be parseable.
568 /// use std::str::FromStr;
570 /// assert_eq!(FromStr::from_str("true"), Ok(true));
571 /// assert_eq!(FromStr::from_str("false"), Ok(false));
572 /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
575 /// Note, in many cases, the `.parse()` method on `str` is more proper.
578 /// assert_eq!("true".parse(), Ok(true));
579 /// assert_eq!("false".parse(), Ok(false));
580 /// assert!("not even a boolean".parse::<bool>().is_err());
583 fn from_str(s: &str) -> Result<bool, ParseBoolError> {
586 "false" => Ok(false),
587 _ => Err(ParseBoolError),