]> git.proxmox.com Git - rustc.git/blame - library/core/src/str/traits.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / library / core / src / str / traits.rs
CommitLineData
1b1a35ee
XL
1//! Trait implementations for `str`.
2
3use crate::cmp::Ordering;
4use crate::ops;
5use crate::ptr;
6use crate::slice::SliceIndex;
7
8use super::ParseBoolError;
9
10/// Implements ordering of strings.
11///
29967ef6 12/// Strings are ordered [lexicographically](Ord#lexicographical-comparison) by their byte values. This orders Unicode code
1b1a35ee
XL
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 Ord for str {
19 #[inline]
20 fn cmp(&self, other: &str) -> Ordering {
21 self.as_bytes().cmp(other.as_bytes())
22 }
23}
24
25#[stable(feature = "rust1", since = "1.0.0")]
26impl PartialEq for str {
27 #[inline]
28 fn eq(&self, other: &str) -> bool {
29 self.as_bytes() == other.as_bytes()
30 }
31 #[inline]
32 fn ne(&self, other: &str) -> bool {
33 !(*self).eq(other)
34 }
35}
36
37#[stable(feature = "rust1", since = "1.0.0")]
38impl Eq for str {}
39
40/// Implements comparison operations on strings.
41///
29967ef6 42/// Strings are compared [lexicographically](Ord#lexicographical-comparison) by their byte values. This compares Unicode code
1b1a35ee
XL
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
46/// the `str` type.
47#[stable(feature = "rust1", since = "1.0.0")]
48impl PartialOrd for str {
49 #[inline]
50 fn partial_cmp(&self, other: &str) -> Option<Ordering> {
51 Some(self.cmp(other))
52 }
53}
54
55#[stable(feature = "rust1", since = "1.0.0")]
56impl<I> ops::Index<I> for str
57where
58 I: SliceIndex<str>,
59{
60 type Output = I::Output;
61
62 #[inline]
63 fn index(&self, index: I) -> &I::Output {
64 index.index(self)
65 }
66}
67
68#[stable(feature = "rust1", since = "1.0.0")]
69impl<I> ops::IndexMut<I> for str
70where
71 I: SliceIndex<str>,
72{
73 #[inline]
74 fn index_mut(&mut self, index: I) -> &mut I::Output {
75 index.index_mut(self)
76 }
77}
78
79#[inline(never)]
80#[cold]
81#[track_caller]
82fn str_index_overflow_fail() -> ! {
83 panic!("attempted to index str up to maximum usize");
84}
85
86/// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
87///
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.
91///
29967ef6 92/// This operation is *O*(1).
1b1a35ee
XL
93///
94/// Prior to 1.20.0, these indexing operations were still supported by
95/// direct implementation of `Index` and `IndexMut`.
96///
97/// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
98#[stable(feature = "str_checked_slicing", since = "1.20.0")]
99unsafe impl SliceIndex<str> for ops::RangeFull {
100 type Output = str;
101 #[inline]
102 fn get(self, slice: &str) -> Option<&Self::Output> {
103 Some(slice)
104 }
105 #[inline]
106 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
107 Some(slice)
108 }
109 #[inline]
110 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
111 slice
112 }
113 #[inline]
114 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
115 slice
116 }
117 #[inline]
118 fn index(self, slice: &str) -> &Self::Output {
119 slice
120 }
121 #[inline]
122 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
123 slice
124 }
125}
126
127/// Implements substring slicing with syntax `&self[begin .. end]` or `&mut
128/// self[begin .. end]`.
129///
130/// Returns a slice of the given string from the byte range
131/// [`begin`, `end`).
132///
29967ef6 133/// This operation is *O*(1).
1b1a35ee
XL
134///
135/// Prior to 1.20.0, these indexing operations were still supported by
136/// direct implementation of `Index` and `IndexMut`.
137///
138/// # Panics
139///
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
142/// `end > len`.
143///
144/// # Examples
145///
146/// ```
147/// let s = "Löwe 老虎 Léopard";
148/// assert_eq!(&s[0 .. 1], "L");
149///
150/// assert_eq!(&s[1 .. 9], "öwe 老");
151///
152/// // these will panic:
153/// // byte 2 lies within `ö`:
154/// // &s[2 ..3];
155///
156/// // byte 8 lies within `老`
157/// // &s[1 .. 8];
158///
159/// // byte 100 is outside the string
160/// // &s[3 .. 100];
161/// ```
162#[stable(feature = "str_checked_slicing", since = "1.20.0")]
163unsafe impl SliceIndex<str> for ops::Range<usize> {
164 type Output = str;
165 #[inline]
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)
170 {
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) })
175 } else {
176 None
177 }
178 }
179 #[inline]
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)
184 {
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) })
188 } else {
189 None
190 }
191 }
192 #[inline]
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
200 }
201 #[inline]
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
208 }
209 #[inline]
210 fn index(self, slice: &str) -> &Self::Output {
211 let (start, end) = (self.start, self.end);
212 match self.get(slice) {
213 Some(s) => s,
214 None => super::slice_error_fail(slice, start, end),
215 }
216 }
217 #[inline]
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)
224 {
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) }
228 } else {
229 super::slice_error_fail(slice, self.start, self.end)
230 }
231 }
232}
233
234/// Implements substring slicing with syntax `&self[.. end]` or `&mut
235/// self[.. end]`.
236///
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]`.
239///
29967ef6 240/// This operation is *O*(1).
1b1a35ee
XL
241///
242/// Prior to 1.20.0, these indexing operations were still supported by
243/// direct implementation of `Index` and `IndexMut`.
244///
245/// # Panics
246///
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")]
250unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
251 type Output = str;
252 #[inline]
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) })
258 } else {
259 None
260 }
261 }
262 #[inline]
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) })
268 } else {
269 None
270 }
271 }
272 #[inline]
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
277 }
278 #[inline]
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
283 }
284 #[inline]
285 fn index(self, slice: &str) -> &Self::Output {
286 let end = self.end;
287 match self.get(slice) {
288 Some(s) => s,
289 None => super::slice_error_fail(slice, 0, end),
290 }
291 }
292 #[inline]
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) }
298 } else {
299 super::slice_error_fail(slice, 0, self.end)
300 }
301 }
302}
303
304/// Implements substring slicing with syntax `&self[begin ..]` or `&mut
305/// self[begin ..]`.
306///
307/// Returns a slice of the given string from the byte range [`begin`,
308/// `len`). Equivalent to `&self[begin .. len]` or `&mut self[begin ..
309/// len]`.
310///
29967ef6 311/// This operation is *O*(1).
1b1a35ee
XL
312///
313/// Prior to 1.20.0, these indexing operations were still supported by
314/// direct implementation of `Index` and `IndexMut`.
315///
316/// # Panics
317///
318/// Panics if `begin` does not point to the starting byte offset of
319/// a character (as defined by `is_char_boundary`), or if `begin > len`.
320#[stable(feature = "str_checked_slicing", since = "1.20.0")]
321unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
322 type Output = str;
323 #[inline]
324 fn get(self, slice: &str) -> Option<&Self::Output> {
325 if slice.is_char_boundary(self.start) {
326 // SAFETY: just checked that `start` is on a char boundary,
327 // and we are passing in a safe reference, so the return value will also be one.
328 Some(unsafe { &*self.get_unchecked(slice) })
329 } else {
330 None
331 }
332 }
333 #[inline]
334 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
335 if slice.is_char_boundary(self.start) {
336 // SAFETY: just checked that `start` is on a char boundary,
337 // and we are passing in a safe reference, so the return value will also be one.
338 Some(unsafe { &mut *self.get_unchecked_mut(slice) })
339 } else {
340 None
341 }
342 }
343 #[inline]
344 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
345 let slice = slice as *const [u8];
346 // SAFETY: the caller guarantees that `self` is in bounds of `slice`
347 // which satisfies all the conditions for `add`.
348 let ptr = unsafe { slice.as_ptr().add(self.start) };
349 let len = slice.len() - self.start;
350 ptr::slice_from_raw_parts(ptr, len) as *const str
351 }
352 #[inline]
353 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
354 let slice = slice as *mut [u8];
355 // SAFETY: identical to `get_unchecked`.
356 let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
357 let len = slice.len() - self.start;
358 ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
359 }
360 #[inline]
361 fn index(self, slice: &str) -> &Self::Output {
362 let (start, end) = (self.start, slice.len());
363 match self.get(slice) {
364 Some(s) => s,
365 None => super::slice_error_fail(slice, start, end),
366 }
367 }
368 #[inline]
369 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
370 if slice.is_char_boundary(self.start) {
371 // SAFETY: just checked that `start` is on a char boundary,
372 // and we are passing in a safe reference, so the return value will also be one.
373 unsafe { &mut *self.get_unchecked_mut(slice) }
374 } else {
375 super::slice_error_fail(slice, self.start, slice.len())
376 }
377 }
378}
379
380/// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut
381/// self[begin ..= end]`.
382///
383/// Returns a slice of the given string from the byte range
384/// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut
385/// self[begin .. end + 1]`, except if `end` has the maximum value for
386/// `usize`.
387///
29967ef6 388/// This operation is *O*(1).
1b1a35ee
XL
389///
390/// # Panics
391///
392/// Panics if `begin` does not point to the starting byte offset of
393/// a character (as defined by `is_char_boundary`), if `end` does not point
394/// to the ending byte offset of a character (`end + 1` is either a starting
395/// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
396#[stable(feature = "inclusive_range", since = "1.26.0")]
397unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
398 type Output = str;
399 #[inline]
400 fn get(self, slice: &str) -> Option<&Self::Output> {
29967ef6 401 if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
1b1a35ee
XL
402 }
403 #[inline]
404 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
29967ef6 405 if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
1b1a35ee
XL
406 }
407 #[inline]
408 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
409 // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
29967ef6 410 unsafe { self.into_slice_range().get_unchecked(slice) }
1b1a35ee
XL
411 }
412 #[inline]
413 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
414 // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
29967ef6 415 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
1b1a35ee
XL
416 }
417 #[inline]
418 fn index(self, slice: &str) -> &Self::Output {
419 if *self.end() == usize::MAX {
420 str_index_overflow_fail();
421 }
29967ef6 422 self.into_slice_range().index(slice)
1b1a35ee
XL
423 }
424 #[inline]
425 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
426 if *self.end() == usize::MAX {
427 str_index_overflow_fail();
428 }
29967ef6 429 self.into_slice_range().index_mut(slice)
1b1a35ee
XL
430 }
431}
432
433/// Implements substring slicing with syntax `&self[..= end]` or `&mut
434/// self[..= end]`.
435///
436/// Returns a slice of the given string from the byte range [0, `end`].
437/// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum
438/// value for `usize`.
439///
29967ef6 440/// This operation is *O*(1).
1b1a35ee
XL
441///
442/// # Panics
443///
444/// Panics if `end` does not point to the ending byte offset of a character
445/// (`end + 1` is either a starting byte offset as defined by
446/// `is_char_boundary`, or equal to `len`), or if `end >= len`.
447#[stable(feature = "inclusive_range", since = "1.26.0")]
448unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> {
449 type Output = str;
450 #[inline]
451 fn get(self, slice: &str) -> Option<&Self::Output> {
452 if self.end == usize::MAX { None } else { (..self.end + 1).get(slice) }
453 }
454 #[inline]
455 fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
456 if self.end == usize::MAX { None } else { (..self.end + 1).get_mut(slice) }
457 }
458 #[inline]
459 unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
460 // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
461 unsafe { (..self.end + 1).get_unchecked(slice) }
462 }
463 #[inline]
464 unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
465 // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
466 unsafe { (..self.end + 1).get_unchecked_mut(slice) }
467 }
468 #[inline]
469 fn index(self, slice: &str) -> &Self::Output {
470 if self.end == usize::MAX {
471 str_index_overflow_fail();
472 }
473 (..self.end + 1).index(slice)
474 }
475 #[inline]
476 fn index_mut(self, slice: &mut str) -> &mut Self::Output {
477 if self.end == usize::MAX {
478 str_index_overflow_fail();
479 }
480 (..self.end + 1).index_mut(slice)
481 }
482}
483
484/// Parse a value from a string
485///
486/// `FromStr`'s [`from_str`] method is often used implicitly, through
487/// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
488///
489/// [`from_str`]: FromStr::from_str
490/// [`parse`]: str::parse
491///
492/// `FromStr` does not have a lifetime parameter, and so you can only parse types
493/// that do not contain a lifetime parameter themselves. In other words, you can
494/// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that
495/// contains an `i32`, but not one that contains an `&i32`.
496///
497/// # Examples
498///
499/// Basic implementation of `FromStr` on an example `Point` type:
500///
501/// ```
502/// use std::str::FromStr;
503/// use std::num::ParseIntError;
504///
505/// #[derive(Debug, PartialEq)]
506/// struct Point {
507/// x: i32,
508/// y: i32
509/// }
510///
511/// impl FromStr for Point {
512/// type Err = ParseIntError;
513///
514/// fn from_str(s: &str) -> Result<Self, Self::Err> {
515/// let coords: Vec<&str> = s.trim_matches(|p| p == '(' || p == ')' )
516/// .split(',')
517/// .collect();
518///
519/// let x_fromstr = coords[0].parse::<i32>()?;
520/// let y_fromstr = coords[1].parse::<i32>()?;
521///
522/// Ok(Point { x: x_fromstr, y: y_fromstr })
523/// }
524/// }
525///
526/// let p = Point::from_str("(1,2)");
527/// assert_eq!(p.unwrap(), Point{ x: 1, y: 2} )
528/// ```
529#[stable(feature = "rust1", since = "1.0.0")]
530pub trait FromStr: Sized {
531 /// The associated error which can be returned from parsing.
532 #[stable(feature = "rust1", since = "1.0.0")]
533 type Err;
534
535 /// Parses a string `s` to return a value of this type.
536 ///
537 /// If parsing succeeds, return the value inside [`Ok`], otherwise
538 /// when the string is ill-formatted return an error specific to the
539 /// inside [`Err`]. The error type is specific to implementation of the trait.
540 ///
541 /// # Examples
542 ///
6a06907d 543 /// Basic usage with [`i32`], a type that implements `FromStr`:
1b1a35ee
XL
544 ///
545 /// ```
546 /// use std::str::FromStr;
547 ///
548 /// let s = "5";
549 /// let x = i32::from_str(s).unwrap();
550 ///
551 /// assert_eq!(5, x);
552 /// ```
553 #[stable(feature = "rust1", since = "1.0.0")]
554 fn from_str(s: &str) -> Result<Self, Self::Err>;
555}
556
557#[stable(feature = "rust1", since = "1.0.0")]
558impl FromStr for bool {
559 type Err = ParseBoolError;
560
561 /// Parse a `bool` from a string.
562 ///
563 /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not
564 /// actually be parseable.
565 ///
566 /// # Examples
567 ///
568 /// ```
569 /// use std::str::FromStr;
570 ///
571 /// assert_eq!(FromStr::from_str("true"), Ok(true));
572 /// assert_eq!(FromStr::from_str("false"), Ok(false));
573 /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
574 /// ```
575 ///
576 /// Note, in many cases, the `.parse()` method on `str` is more proper.
577 ///
578 /// ```
579 /// assert_eq!("true".parse(), Ok(true));
580 /// assert_eq!("false".parse(), Ok(false));
581 /// assert!("not even a boolean".parse::<bool>().is_err());
582 /// ```
583 #[inline]
584 fn from_str(s: &str) -> Result<bool, ParseBoolError> {
585 match s {
586 "true" => Ok(true),
587 "false" => Ok(false),
588 _ => Err(ParseBoolError { _priv: () }),
589 }
590 }
591}