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 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
57 impl<I
> const ops
::Index
<I
> for str
59 I
: ~const SliceIndex
<str>,
61 type Output
= I
::Output
;
64 fn index(&self, index
: I
) -> &I
::Output
{
69 #[stable(feature = "rust1", since = "1.0.0")]
70 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
71 impl<I
> const ops
::IndexMut
<I
> for str
73 I
: ~const SliceIndex
<str>,
76 fn index_mut(&mut self, index
: I
) -> &mut I
::Output
{
84 const fn str_index_overflow_fail() -> ! {
85 panic
!("attempted to index str up to maximum usize");
88 /// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
90 /// Returns a slice of the whole string, i.e., returns `&self` or `&mut
91 /// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike
92 /// other indexing operations, this can never panic.
94 /// This operation is *O*(1).
96 /// Prior to 1.20.0, these indexing operations were still supported by
97 /// direct implementation of `Index` and `IndexMut`.
99 /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
100 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
101 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
102 unsafe impl const SliceIndex
<str> for ops
::RangeFull
{
105 fn get(self, slice
: &str) -> Option
<&Self::Output
> {
109 fn get_mut(self, slice
: &mut str) -> Option
<&mut Self::Output
> {
113 unsafe fn get_unchecked(self, slice
: *const str) -> *const Self::Output
{
117 unsafe fn get_unchecked_mut(self, slice
: *mut str) -> *mut Self::Output
{
121 fn index(self, slice
: &str) -> &Self::Output
{
125 fn index_mut(self, slice
: &mut str) -> &mut Self::Output
{
130 /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut
131 /// self[begin .. end]`.
133 /// Returns a slice of the given string from the byte range
134 /// [`begin`, `end`).
136 /// This operation is *O*(1).
138 /// Prior to 1.20.0, these indexing operations were still supported by
139 /// direct implementation of `Index` and `IndexMut`.
143 /// Panics if `begin` or `end` does not point to the starting byte offset of
144 /// a character (as defined by `is_char_boundary`), if `begin > end`, or if
150 /// let s = "Löwe 老虎 Léopard";
151 /// assert_eq!(&s[0 .. 1], "L");
153 /// assert_eq!(&s[1 .. 9], "öwe 老");
155 /// // these will panic:
156 /// // byte 2 lies within `ö`:
159 /// // byte 8 lies within `老`
162 /// // byte 100 is outside the string
165 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
166 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
167 unsafe impl const SliceIndex
<str> for ops
::Range
<usize> {
170 fn get(self, slice
: &str) -> Option
<&Self::Output
> {
171 if self.start
<= self.end
172 && slice
.is_char_boundary(self.start
)
173 && slice
.is_char_boundary(self.end
)
175 // SAFETY: just checked that `start` and `end` are on a char boundary,
176 // and we are passing in a safe reference, so the return value will also be one.
177 // We also checked char boundaries, so this is valid UTF-8.
178 Some(unsafe { &*self.get_unchecked(slice) }
)
184 fn get_mut(self, slice
: &mut str) -> Option
<&mut Self::Output
> {
185 if self.start
<= self.end
186 && slice
.is_char_boundary(self.start
)
187 && slice
.is_char_boundary(self.end
)
189 // SAFETY: just checked that `start` and `end` are on a char boundary.
190 // We know the pointer is unique because we got it from `slice`.
191 Some(unsafe { &mut *self.get_unchecked_mut(slice) }
)
197 unsafe fn get_unchecked(self, slice
: *const str) -> *const Self::Output
{
198 let slice
= slice
as *const [u8];
199 // SAFETY: the caller guarantees that `self` is in bounds of `slice`
200 // which satisfies all the conditions for `add`.
201 let ptr
= unsafe { slice.as_ptr().add(self.start) }
;
202 let len
= self.end
- self.start
;
203 ptr
::slice_from_raw_parts(ptr
, len
) as *const str
206 unsafe fn get_unchecked_mut(self, slice
: *mut str) -> *mut Self::Output
{
207 let slice
= slice
as *mut [u8];
208 // SAFETY: see comments for `get_unchecked`.
209 let ptr
= unsafe { slice.as_mut_ptr().add(self.start) }
;
210 let len
= self.end
- self.start
;
211 ptr
::slice_from_raw_parts_mut(ptr
, len
) as *mut str
214 fn index(self, slice
: &str) -> &Self::Output
{
215 let (start
, end
) = (self.start
, self.end
);
216 match self.get(slice
) {
218 None
=> super::slice_error_fail(slice
, start
, end
),
222 fn index_mut(self, slice
: &mut str) -> &mut Self::Output
{
223 // is_char_boundary checks that the index is in [0, .len()]
224 // cannot reuse `get` as above, because of NLL trouble
225 if self.start
<= self.end
226 && slice
.is_char_boundary(self.start
)
227 && slice
.is_char_boundary(self.end
)
229 // SAFETY: just checked that `start` and `end` are on a char boundary,
230 // and we are passing in a safe reference, so the return value will also be one.
231 unsafe { &mut *self.get_unchecked_mut(slice) }
233 super::slice_error_fail(slice
, self.start
, self.end
)
238 /// Implements substring slicing with syntax `&self[.. end]` or `&mut
241 /// Returns a slice of the given string from the byte range \[0, `end`).
242 /// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`.
244 /// This operation is *O*(1).
246 /// Prior to 1.20.0, these indexing operations were still supported by
247 /// direct implementation of `Index` and `IndexMut`.
251 /// Panics if `end` does not point to the starting byte offset of a
252 /// character (as defined by `is_char_boundary`), or if `end > len`.
253 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
254 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
255 unsafe impl const SliceIndex
<str> for ops
::RangeTo
<usize> {
258 fn get(self, slice
: &str) -> Option
<&Self::Output
> {
259 if slice
.is_char_boundary(self.end
) {
260 // SAFETY: just checked that `end` is on a char boundary,
261 // and we are passing in a safe reference, so the return value will also be one.
262 Some(unsafe { &*self.get_unchecked(slice) }
)
268 fn get_mut(self, slice
: &mut str) -> Option
<&mut Self::Output
> {
269 if slice
.is_char_boundary(self.end
) {
270 // SAFETY: just checked that `end` is on a char boundary,
271 // and we are passing in a safe reference, so the return value will also be one.
272 Some(unsafe { &mut *self.get_unchecked_mut(slice) }
)
278 unsafe fn get_unchecked(self, slice
: *const str) -> *const Self::Output
{
279 let slice
= slice
as *const [u8];
280 let ptr
= slice
.as_ptr();
281 ptr
::slice_from_raw_parts(ptr
, self.end
) as *const str
284 unsafe fn get_unchecked_mut(self, slice
: *mut str) -> *mut Self::Output
{
285 let slice
= slice
as *mut [u8];
286 let ptr
= slice
.as_mut_ptr();
287 ptr
::slice_from_raw_parts_mut(ptr
, self.end
) as *mut str
290 fn index(self, slice
: &str) -> &Self::Output
{
292 match self.get(slice
) {
294 None
=> super::slice_error_fail(slice
, 0, end
),
298 fn index_mut(self, slice
: &mut str) -> &mut Self::Output
{
299 if slice
.is_char_boundary(self.end
) {
300 // SAFETY: just checked that `end` is on a char boundary,
301 // and we are passing in a safe reference, so the return value will also be one.
302 unsafe { &mut *self.get_unchecked_mut(slice) }
304 super::slice_error_fail(slice
, 0, self.end
)
309 /// Implements substring slicing with syntax `&self[begin ..]` or `&mut
312 /// Returns a slice of the given string from the byte range \[`begin`, `len`).
313 /// Equivalent to `&self[begin .. len]` or `&mut self[begin .. len]`.
315 /// This operation is *O*(1).
317 /// Prior to 1.20.0, these indexing operations were still supported by
318 /// direct implementation of `Index` and `IndexMut`.
322 /// Panics if `begin` does not point to the starting byte offset of
323 /// a character (as defined by `is_char_boundary`), or if `begin > len`.
324 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
325 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
326 unsafe impl const SliceIndex
<str> for ops
::RangeFrom
<usize> {
329 fn get(self, slice
: &str) -> Option
<&Self::Output
> {
330 if slice
.is_char_boundary(self.start
) {
331 // SAFETY: just checked that `start` is on a char boundary,
332 // and we are passing in a safe reference, so the return value will also be one.
333 Some(unsafe { &*self.get_unchecked(slice) }
)
339 fn get_mut(self, slice
: &mut str) -> Option
<&mut Self::Output
> {
340 if slice
.is_char_boundary(self.start
) {
341 // SAFETY: just checked that `start` is on a char boundary,
342 // and we are passing in a safe reference, so the return value will also be one.
343 Some(unsafe { &mut *self.get_unchecked_mut(slice) }
)
349 unsafe fn get_unchecked(self, slice
: *const str) -> *const Self::Output
{
350 let slice
= slice
as *const [u8];
351 // SAFETY: the caller guarantees that `self` is in bounds of `slice`
352 // which satisfies all the conditions for `add`.
353 let ptr
= unsafe { slice.as_ptr().add(self.start) }
;
354 let len
= slice
.len() - self.start
;
355 ptr
::slice_from_raw_parts(ptr
, len
) as *const str
358 unsafe fn get_unchecked_mut(self, slice
: *mut str) -> *mut Self::Output
{
359 let slice
= slice
as *mut [u8];
360 // SAFETY: identical to `get_unchecked`.
361 let ptr
= unsafe { slice.as_mut_ptr().add(self.start) }
;
362 let len
= slice
.len() - self.start
;
363 ptr
::slice_from_raw_parts_mut(ptr
, len
) as *mut str
366 fn index(self, slice
: &str) -> &Self::Output
{
367 let (start
, end
) = (self.start
, slice
.len());
368 match self.get(slice
) {
370 None
=> super::slice_error_fail(slice
, start
, end
),
374 fn index_mut(self, slice
: &mut str) -> &mut Self::Output
{
375 if slice
.is_char_boundary(self.start
) {
376 // SAFETY: just checked that `start` is on a char boundary,
377 // and we are passing in a safe reference, so the return value will also be one.
378 unsafe { &mut *self.get_unchecked_mut(slice) }
380 super::slice_error_fail(slice
, self.start
, slice
.len())
385 /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut
386 /// self[begin ..= end]`.
388 /// Returns a slice of the given string from the byte range
389 /// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut
390 /// self[begin .. end + 1]`, except if `end` has the maximum value for
393 /// This operation is *O*(1).
397 /// Panics if `begin` does not point to the starting byte offset of
398 /// a character (as defined by `is_char_boundary`), if `end` does not point
399 /// to the ending byte offset of a character (`end + 1` is either a starting
400 /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
401 #[stable(feature = "inclusive_range", since = "1.26.0")]
402 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
403 unsafe impl const SliceIndex
<str> for ops
::RangeInclusive
<usize> {
406 fn get(self, slice
: &str) -> Option
<&Self::Output
> {
407 if *self.end() == usize::MAX { None }
else { self.into_slice_range().get(slice) }
410 fn get_mut(self, slice
: &mut str) -> Option
<&mut Self::Output
> {
411 if *self.end() == usize::MAX { None }
else { self.into_slice_range().get_mut(slice) }
414 unsafe fn get_unchecked(self, slice
: *const str) -> *const Self::Output
{
415 // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
416 unsafe { self.into_slice_range().get_unchecked(slice) }
419 unsafe fn get_unchecked_mut(self, slice
: *mut str) -> *mut Self::Output
{
420 // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
421 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
424 fn index(self, slice
: &str) -> &Self::Output
{
425 if *self.end() == usize::MAX
{
426 str_index_overflow_fail();
428 self.into_slice_range().index(slice
)
431 fn index_mut(self, slice
: &mut str) -> &mut Self::Output
{
432 if *self.end() == usize::MAX
{
433 str_index_overflow_fail();
435 self.into_slice_range().index_mut(slice
)
439 /// Implements substring slicing with syntax `&self[..= end]` or `&mut
442 /// Returns a slice of the given string from the byte range \[0, `end`\].
443 /// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum
444 /// value for `usize`.
446 /// This operation is *O*(1).
450 /// Panics if `end` does not point to the ending byte offset of a character
451 /// (`end + 1` is either a starting byte offset as defined by
452 /// `is_char_boundary`, or equal to `len`), or if `end >= len`.
453 #[stable(feature = "inclusive_range", since = "1.26.0")]
454 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
455 unsafe impl const SliceIndex
<str> for ops
::RangeToInclusive
<usize> {
458 fn get(self, slice
: &str) -> Option
<&Self::Output
> {
459 if self.end
== usize::MAX { None }
else { (..self.end + 1).get(slice) }
462 fn get_mut(self, slice
: &mut str) -> Option
<&mut Self::Output
> {
463 if self.end
== usize::MAX { None }
else { (..self.end + 1).get_mut(slice) }
466 unsafe fn get_unchecked(self, slice
: *const str) -> *const Self::Output
{
467 // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
468 unsafe { (..self.end + 1).get_unchecked(slice) }
471 unsafe fn get_unchecked_mut(self, slice
: *mut str) -> *mut Self::Output
{
472 // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
473 unsafe { (..self.end + 1).get_unchecked_mut(slice) }
476 fn index(self, slice
: &str) -> &Self::Output
{
477 if self.end
== usize::MAX
{
478 str_index_overflow_fail();
480 (..self.end
+ 1).index(slice
)
483 fn index_mut(self, slice
: &mut str) -> &mut Self::Output
{
484 if self.end
== usize::MAX
{
485 str_index_overflow_fail();
487 (..self.end
+ 1).index_mut(slice
)
491 /// Parse a value from a string
493 /// `FromStr`'s [`from_str`] method is often used implicitly, through
494 /// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
496 /// [`from_str`]: FromStr::from_str
497 /// [`parse`]: str::parse
499 /// `FromStr` does not have a lifetime parameter, and so you can only parse types
500 /// that do not contain a lifetime parameter themselves. In other words, you can
501 /// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that
502 /// contains an `i32`, but not one that contains an `&i32`.
506 /// Basic implementation of `FromStr` on an example `Point` type:
509 /// use std::str::FromStr;
510 /// use std::num::ParseIntError;
512 /// #[derive(Debug, PartialEq)]
518 /// impl FromStr for Point {
519 /// type Err = ParseIntError;
521 /// fn from_str(s: &str) -> Result<Self, Self::Err> {
523 /// .strip_prefix('(')
524 /// .and_then(|s| s.strip_suffix(')'))
525 /// .and_then(|s| s.split_once(','))
528 /// let x_fromstr = x.parse::<i32>()?;
529 /// let y_fromstr = y.parse::<i32>()?;
531 /// Ok(Point { x: x_fromstr, y: y_fromstr })
535 /// let expected = Ok(Point { x: 1, y: 2 });
537 /// assert_eq!(Point::from_str("(1,2)"), expected);
538 /// // Implicit calls, through parse
539 /// assert_eq!("(1,2)".parse(), expected);
540 /// assert_eq!("(1,2)".parse::<Point>(), expected);
542 #[stable(feature = "rust1", since = "1.0.0")]
543 pub trait FromStr
: Sized
{
544 /// The associated error which can be returned from parsing.
545 #[stable(feature = "rust1", since = "1.0.0")]
548 /// Parses a string `s` to return a value of this type.
550 /// If parsing succeeds, return the value inside [`Ok`], otherwise
551 /// when the string is ill-formatted return an error specific to the
552 /// inside [`Err`]. The error type is specific to the implementation of the trait.
556 /// Basic usage with [`i32`], a type that implements `FromStr`:
559 /// use std::str::FromStr;
562 /// let x = i32::from_str(s).unwrap();
564 /// assert_eq!(5, x);
566 #[stable(feature = "rust1", since = "1.0.0")]
567 fn from_str(s
: &str) -> Result
<Self, Self::Err
>;
570 #[stable(feature = "rust1", since = "1.0.0")]
571 impl FromStr
for bool
{
572 type Err
= ParseBoolError
;
574 /// Parse a `bool` from a string.
576 /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not
577 /// actually be parseable.
582 /// use std::str::FromStr;
584 /// assert_eq!(FromStr::from_str("true"), Ok(true));
585 /// assert_eq!(FromStr::from_str("false"), Ok(false));
586 /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
589 /// Note, in many cases, the `.parse()` method on `str` is more proper.
592 /// assert_eq!("true".parse(), Ok(true));
593 /// assert_eq!("false".parse(), Ok(false));
594 /// assert!("not even a boolean".parse::<bool>().is_err());
597 fn from_str(s
: &str) -> Result
<bool
, ParseBoolError
> {
600 "false" => Ok(false),
601 _
=> Err(ParseBoolError
),