1 | //! Trait implementations for `str`. |
---|---|
2 | |
3 | use super::ParseBoolError; |
4 | use crate::cmp::Ordering; |
5 | use crate::intrinsics::unchecked_sub; |
6 | use crate::slice::SliceIndex; |
7 | use crate::ub_checks::assert_unsafe_precondition; |
8 | use crate::{ops, ptr, range}; |
9 | |
10 | /// Implements ordering of strings. |
11 | /// |
12 | /// Strings are ordered [lexicographically](Ord#lexicographical-comparison) by their byte values. This orders Unicode code |
13 | /// points based on their positions in the code charts. This is not necessarily the same as |
14 | /// "alphabetical" order, which varies by language and locale. Sorting strings according to |
15 | /// culturally-accepted standards requires locale-specific data that is outside the scope of |
16 | /// the `str` type. |
17 | #[stable(feature = "rust1", since = "1.0.0")] |
18 | impl 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")] |
26 | impl PartialEq for str { |
27 | #[inline] |
28 | fn eq(&self, other: &str) -> bool { |
29 | self.as_bytes() == other.as_bytes() |
30 | } |
31 | } |
32 | |
33 | #[stable(feature = "rust1", since = "1.0.0")] |
34 | impl Eq for str {} |
35 | |
36 | /// Implements comparison operations on strings. |
37 | /// |
38 | /// Strings are compared [lexicographically](Ord#lexicographical-comparison) by their byte values. This compares Unicode code |
39 | /// points based on their positions in the code charts. This is not necessarily the same as |
40 | /// "alphabetical" order, which varies by language and locale. Comparing strings according to |
41 | /// culturally-accepted standards requires locale-specific data that is outside the scope of |
42 | /// the `str` type. |
43 | #[stable(feature = "rust1", since = "1.0.0")] |
44 | impl PartialOrd for str { |
45 | #[inline] |
46 | fn partial_cmp(&self, other: &str) -> Option<Ordering> { |
47 | Some(self.cmp(other)) |
48 | } |
49 | } |
50 | |
51 | #[stable(feature = "rust1", since = "1.0.0")] |
52 | impl<I> ops::Index<I> for str |
53 | where |
54 | I: SliceIndex<str>, |
55 | { |
56 | type Output = I::Output; |
57 | |
58 | #[inline] |
59 | fn index(&self, index: I) -> &I::Output { |
60 | index.index(self) |
61 | } |
62 | } |
63 | |
64 | #[stable(feature = "rust1", since = "1.0.0")] |
65 | impl<I> ops::IndexMut<I> for str |
66 | where |
67 | I: SliceIndex<str>, |
68 | { |
69 | #[inline] |
70 | fn index_mut(&mut self, index: I) -> &mut I::Output { |
71 | index.index_mut(self) |
72 | } |
73 | } |
74 | |
75 | #[inline(never)] |
76 | #[cold] |
77 | #[track_caller] |
78 | const fn str_index_overflow_fail() -> ! { |
79 | panic!("attempted to index str up to maximum usize"); |
80 | } |
81 | |
82 | /// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`. |
83 | /// |
84 | /// Returns a slice of the whole string, i.e., returns `&self` or `&mut |
85 | /// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike |
86 | /// other indexing operations, this can never panic. |
87 | /// |
88 | /// This operation is *O*(1). |
89 | /// |
90 | /// Prior to 1.20.0, these indexing operations were still supported by |
91 | /// direct implementation of `Index` and `IndexMut`. |
92 | /// |
93 | /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. |
94 | #[stable(feature = "str_checked_slicing", since = "1.20.0")] |
95 | unsafe impl SliceIndex<str> for ops::RangeFull { |
96 | type Output = str; |
97 | #[inline] |
98 | fn get(self, slice: &str) -> Option<&Self::Output> { |
99 | Some(slice) |
100 | } |
101 | #[inline] |
102 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
103 | Some(slice) |
104 | } |
105 | #[inline] |
106 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
107 | slice |
108 | } |
109 | #[inline] |
110 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
111 | slice |
112 | } |
113 | #[inline] |
114 | fn index(self, slice: &str) -> &Self::Output { |
115 | slice |
116 | } |
117 | #[inline] |
118 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
119 | slice |
120 | } |
121 | } |
122 | |
123 | /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut |
124 | /// self[begin .. end]`. |
125 | /// |
126 | /// Returns a slice of the given string from the byte range |
127 | /// [`begin`, `end`). |
128 | /// |
129 | /// This operation is *O*(1). |
130 | /// |
131 | /// Prior to 1.20.0, these indexing operations were still supported by |
132 | /// direct implementation of `Index` and `IndexMut`. |
133 | /// |
134 | /// # Panics |
135 | /// |
136 | /// Panics if `begin` or `end` does not point to the starting byte offset of |
137 | /// a character (as defined by `is_char_boundary`), if `begin > end`, or if |
138 | /// `end > len`. |
139 | /// |
140 | /// # Examples |
141 | /// |
142 | /// ``` |
143 | /// let s = "Löwe 老虎 Léopard"; |
144 | /// assert_eq!(&s[0 .. 1], "L"); |
145 | /// |
146 | /// assert_eq!(&s[1 .. 9], "öwe 老"); |
147 | /// |
148 | /// // these will panic: |
149 | /// // byte 2 lies within `ö`: |
150 | /// // &s[2 ..3]; |
151 | /// |
152 | /// // byte 8 lies within `老` |
153 | /// // &s[1 .. 8]; |
154 | /// |
155 | /// // byte 100 is outside the string |
156 | /// // &s[3 .. 100]; |
157 | /// ``` |
158 | #[stable(feature = "str_checked_slicing", since = "1.20.0")] |
159 | unsafe impl SliceIndex<str> for ops::Range<usize> { |
160 | type Output = str; |
161 | #[inline] |
162 | fn get(self, slice: &str) -> Option<&Self::Output> { |
163 | if self.start <= self.end |
164 | && slice.is_char_boundary(self.start) |
165 | && slice.is_char_boundary(self.end) |
166 | { |
167 | // SAFETY: just checked that `start` and `end` are on a char boundary, |
168 | // and we are passing in a safe reference, so the return value will also be one. |
169 | // We also checked char boundaries, so this is valid UTF-8. |
170 | Some(unsafe { &*self.get_unchecked(slice) }) |
171 | } else { |
172 | None |
173 | } |
174 | } |
175 | #[inline] |
176 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
177 | if self.start <= self.end |
178 | && slice.is_char_boundary(self.start) |
179 | && slice.is_char_boundary(self.end) |
180 | { |
181 | // SAFETY: just checked that `start` and `end` are on a char boundary. |
182 | // We know the pointer is unique because we got it from `slice`. |
183 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
184 | } else { |
185 | None |
186 | } |
187 | } |
188 | #[inline] |
189 | #[track_caller] |
190 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
191 | let slice = slice as *const [u8]; |
192 | |
193 | assert_unsafe_precondition!( |
194 | // We'd like to check that the bounds are on char boundaries, |
195 | // but there's not really a way to do so without reading |
196 | // behind the pointer, which has aliasing implications. |
197 | // It's also not possible to move this check up to |
198 | // `str::get_unchecked` without adding a special function |
199 | // to `SliceIndex` just for this. |
200 | check_library_ub, |
201 | "str::get_unchecked requires that the range is within the string slice", |
202 | ( |
203 | start: usize = self.start, |
204 | end: usize = self.end, |
205 | len: usize = slice.len() |
206 | ) => end >= start && end <= len, |
207 | ); |
208 | |
209 | // SAFETY: the caller guarantees that `self` is in bounds of `slice` |
210 | // which satisfies all the conditions for `add`. |
211 | unsafe { |
212 | let new_len = unchecked_sub(self.end, self.start); |
213 | ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str |
214 | } |
215 | } |
216 | #[inline] |
217 | #[track_caller] |
218 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
219 | let slice = slice as *mut [u8]; |
220 | |
221 | assert_unsafe_precondition!( |
222 | check_library_ub, |
223 | "str::get_unchecked_mut requires that the range is within the string slice", |
224 | ( |
225 | start: usize = self.start, |
226 | end: usize = self.end, |
227 | len: usize = slice.len() |
228 | ) => end >= start && end <= len, |
229 | ); |
230 | |
231 | // SAFETY: see comments for `get_unchecked`. |
232 | unsafe { |
233 | let new_len = unchecked_sub(self.end, self.start); |
234 | ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str |
235 | } |
236 | } |
237 | #[inline] |
238 | fn index(self, slice: &str) -> &Self::Output { |
239 | let (start, end) = (self.start, self.end); |
240 | match self.get(slice) { |
241 | Some(s) => s, |
242 | None => super::slice_error_fail(slice, start, end), |
243 | } |
244 | } |
245 | #[inline] |
246 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
247 | // is_char_boundary checks that the index is in [0, .len()] |
248 | // cannot reuse `get` as above, because of NLL trouble |
249 | if self.start <= self.end |
250 | && slice.is_char_boundary(self.start) |
251 | && slice.is_char_boundary(self.end) |
252 | { |
253 | // SAFETY: just checked that `start` and `end` are on a char boundary, |
254 | // and we are passing in a safe reference, so the return value will also be one. |
255 | unsafe { &mut *self.get_unchecked_mut(slice) } |
256 | } else { |
257 | super::slice_error_fail(slice, self.start, self.end) |
258 | } |
259 | } |
260 | } |
261 | |
262 | #[unstable(feature = "new_range_api", issue = "125687")] |
263 | unsafe impl SliceIndex<str> for range::Range<usize> { |
264 | type Output = str; |
265 | #[inline] |
266 | fn get(self, slice: &str) -> Option<&Self::Output> { |
267 | if 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. |
274 | Some(unsafe { &*self.get_unchecked(slice) }) |
275 | } else { |
276 | None |
277 | } |
278 | } |
279 | #[inline] |
280 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
281 | if 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`. |
287 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
288 | } else { |
289 | None |
290 | } |
291 | } |
292 | #[inline] |
293 | #[track_caller] |
294 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
295 | let slice = slice as *const [u8]; |
296 | |
297 | 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. |
304 | check_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 | ); |
312 | |
313 | // SAFETY: the caller guarantees that `self` is in bounds of `slice` |
314 | // which satisfies all the conditions for `add`. |
315 | unsafe { |
316 | let new_len = unchecked_sub(self.end, self.start); |
317 | ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str |
318 | } |
319 | } |
320 | #[inline] |
321 | #[track_caller] |
322 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
323 | let slice = slice as *mut [u8]; |
324 | |
325 | 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 | ); |
334 | |
335 | // SAFETY: see comments for `get_unchecked`. |
336 | unsafe { |
337 | let 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 str |
339 | } |
340 | } |
341 | #[inline] |
342 | fn index(self, slice: &str) -> &Self::Output { |
343 | let (start, end) = (self.start, self.end); |
344 | match self.get(slice) { |
345 | Some(s) => s, |
346 | None => super::slice_error_fail(slice, start, end), |
347 | } |
348 | } |
349 | #[inline] |
350 | fn 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 |
353 | if 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. |
359 | unsafe { &mut *self.get_unchecked_mut(slice) } |
360 | } else { |
361 | super::slice_error_fail(slice, self.start, self.end) |
362 | } |
363 | } |
364 | } |
365 | |
366 | /// 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")] |
380 | unsafe impl SliceIndex<str> for (ops::Bound<usize>, ops::Bound<usize>) { |
381 | type Output = str; |
382 | |
383 | #[inline] |
384 | fn get(self, slice: &str) -> Option<&str> { |
385 | crate::slice::index::into_range(slice.len(), self)?.get(slice) |
386 | } |
387 | |
388 | #[inline] |
389 | fn get_mut(self, slice: &mut str) -> Option<&mut str> { |
390 | crate::slice::index::into_range(slice.len(), self)?.get_mut(slice) |
391 | } |
392 | |
393 | #[inline] |
394 | unsafe fn get_unchecked(self, slice: *const str) -> *const str { |
395 | let len = (slice as *const [u8]).len(); |
396 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
397 | unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked(slice) } |
398 | } |
399 | |
400 | #[inline] |
401 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut str { |
402 | let len = (slice as *mut [u8]).len(); |
403 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
404 | unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked_mut(slice) } |
405 | } |
406 | |
407 | #[inline] |
408 | fn index(self, slice: &str) -> &str { |
409 | crate::slice::index::into_slice_range(slice.len(), self).index(slice) |
410 | } |
411 | |
412 | #[inline] |
413 | fn index_mut(self, slice: &mut str) -> &mut str { |
414 | crate::slice::index::into_slice_range(slice.len(), self).index_mut(slice) |
415 | } |
416 | } |
417 | |
418 | /// 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 | unsafe impl SliceIndex<str> for ops::RangeTo<usize> { |
435 | type Output = str; |
436 | #[inline] |
437 | fn get(self, slice: &str) -> Option<&Self::Output> { |
438 | if slice.is_char_boundary(self.end) { |
439 | // SAFETY: just checked that `end` is on a char boundary, |
440 | // and we are passing in a safe reference, so the return value will also be one. |
441 | Some(unsafe { &*self.get_unchecked(slice) }) |
442 | } else { |
443 | None |
444 | } |
445 | } |
446 | #[inline] |
447 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
448 | if slice.is_char_boundary(self.end) { |
449 | // SAFETY: just checked that `end` is on a char boundary, |
450 | // and we are passing in a safe reference, so the return value will also be one. |
451 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
452 | } else { |
453 | None |
454 | } |
455 | } |
456 | #[inline] |
457 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
458 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
459 | unsafe { (0..self.end).get_unchecked(slice) } |
460 | } |
461 | #[inline] |
462 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
463 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
464 | unsafe { (0..self.end).get_unchecked_mut(slice) } |
465 | } |
466 | #[inline] |
467 | fn index(self, slice: &str) -> &Self::Output { |
468 | let end = self.end; |
469 | match self.get(slice) { |
470 | Some(s) => s, |
471 | None => super::slice_error_fail(slice, 0, end), |
472 | } |
473 | } |
474 | #[inline] |
475 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
476 | if slice.is_char_boundary(self.end) { |
477 | // SAFETY: just checked that `end` is on a char boundary, |
478 | // and we are passing in a safe reference, so the return value will also be one. |
479 | unsafe { &mut *self.get_unchecked_mut(slice) } |
480 | } else { |
481 | super::slice_error_fail(slice, 0, self.end) |
482 | } |
483 | } |
484 | } |
485 | |
486 | /// Implements substring slicing with syntax `&self[begin ..]` or `&mut |
487 | /// self[begin ..]`. |
488 | /// |
489 | /// Returns a slice of the given string from the byte range \[`begin`, `len`). |
490 | /// Equivalent to `&self[begin .. len]` or `&mut self[begin .. len]`. |
491 | /// |
492 | /// This operation is *O*(1). |
493 | /// |
494 | /// Prior to 1.20.0, these indexing operations were still supported by |
495 | /// direct implementation of `Index` and `IndexMut`. |
496 | /// |
497 | /// # Panics |
498 | /// |
499 | /// Panics if `begin` does not point to the starting byte offset of |
500 | /// a character (as defined by `is_char_boundary`), or if `begin > len`. |
501 | #[stable(feature = "str_checked_slicing", since = "1.20.0")] |
502 | unsafe impl SliceIndex<str> for ops::RangeFrom<usize> { |
503 | type Output = str; |
504 | #[inline] |
505 | fn get(self, slice: &str) -> Option<&Self::Output> { |
506 | if slice.is_char_boundary(self.start) { |
507 | // SAFETY: just checked that `start` is on a char boundary, |
508 | // and we are passing in a safe reference, so the return value will also be one. |
509 | Some(unsafe { &*self.get_unchecked(slice) }) |
510 | } else { |
511 | None |
512 | } |
513 | } |
514 | #[inline] |
515 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
516 | if slice.is_char_boundary(self.start) { |
517 | // SAFETY: just checked that `start` is on a char boundary, |
518 | // and we are passing in a safe reference, so the return value will also be one. |
519 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
520 | } else { |
521 | None |
522 | } |
523 | } |
524 | #[inline] |
525 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
526 | let len = (slice as *const [u8]).len(); |
527 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
528 | unsafe { (self.start..len).get_unchecked(slice) } |
529 | } |
530 | #[inline] |
531 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
532 | let len = (slice as *mut [u8]).len(); |
533 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
534 | unsafe { (self.start..len).get_unchecked_mut(slice) } |
535 | } |
536 | #[inline] |
537 | fn index(self, slice: &str) -> &Self::Output { |
538 | let (start, end) = (self.start, slice.len()); |
539 | match self.get(slice) { |
540 | Some(s) => s, |
541 | None => super::slice_error_fail(slice, start, end), |
542 | } |
543 | } |
544 | #[inline] |
545 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
546 | if slice.is_char_boundary(self.start) { |
547 | // SAFETY: just checked that `start` is on a char boundary, |
548 | // and we are passing in a safe reference, so the return value will also be one. |
549 | unsafe { &mut *self.get_unchecked_mut(slice) } |
550 | } else { |
551 | super::slice_error_fail(slice, self.start, slice.len()) |
552 | } |
553 | } |
554 | } |
555 | |
556 | #[unstable(feature = "new_range_api", issue = "125687")] |
557 | unsafe impl SliceIndex<str> for range::RangeFrom<usize> { |
558 | type Output = str; |
559 | #[inline] |
560 | fn get(self, slice: &str) -> Option<&Self::Output> { |
561 | if slice.is_char_boundary(self.start) { |
562 | // SAFETY: just checked that `start` is on a char boundary, |
563 | // and we are passing in a safe reference, so the return value will also be one. |
564 | Some(unsafe { &*self.get_unchecked(slice) }) |
565 | } else { |
566 | None |
567 | } |
568 | } |
569 | #[inline] |
570 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
571 | if slice.is_char_boundary(self.start) { |
572 | // SAFETY: just checked that `start` is on a char boundary, |
573 | // and we are passing in a safe reference, so the return value will also be one. |
574 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
575 | } else { |
576 | None |
577 | } |
578 | } |
579 | #[inline] |
580 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
581 | let len = (slice as *const [u8]).len(); |
582 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
583 | unsafe { (self.start..len).get_unchecked(slice) } |
584 | } |
585 | #[inline] |
586 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
587 | let len = (slice as *mut [u8]).len(); |
588 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
589 | unsafe { (self.start..len).get_unchecked_mut(slice) } |
590 | } |
591 | #[inline] |
592 | fn index(self, slice: &str) -> &Self::Output { |
593 | let (start, end) = (self.start, slice.len()); |
594 | match self.get(slice) { |
595 | Some(s) => s, |
596 | None => super::slice_error_fail(slice, start, end), |
597 | } |
598 | } |
599 | #[inline] |
600 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
601 | if slice.is_char_boundary(self.start) { |
602 | // SAFETY: just checked that `start` is on a char boundary, |
603 | // and we are passing in a safe reference, so the return value will also be one. |
604 | unsafe { &mut *self.get_unchecked_mut(slice) } |
605 | } else { |
606 | super::slice_error_fail(slice, self.start, slice.len()) |
607 | } |
608 | } |
609 | } |
610 | |
611 | /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut |
612 | /// self[begin ..= end]`. |
613 | /// |
614 | /// Returns a slice of the given string from the byte range |
615 | /// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut |
616 | /// self[begin .. end + 1]`, except if `end` has the maximum value for |
617 | /// `usize`. |
618 | /// |
619 | /// This operation is *O*(1). |
620 | /// |
621 | /// # Panics |
622 | /// |
623 | /// Panics if `begin` does not point to the starting byte offset of |
624 | /// a character (as defined by `is_char_boundary`), if `end` does not point |
625 | /// to the ending byte offset of a character (`end + 1` is either a starting |
626 | /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. |
627 | #[stable(feature = "inclusive_range", since = "1.26.0")] |
628 | unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> { |
629 | type Output = str; |
630 | #[inline] |
631 | fn get(self, slice: &str) -> Option<&Self::Output> { |
632 | if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) } |
633 | } |
634 | #[inline] |
635 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
636 | if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } |
637 | } |
638 | #[inline] |
639 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
640 | // SAFETY: the caller must uphold the safety contract for `get_unchecked`. |
641 | unsafe { self.into_slice_range().get_unchecked(slice) } |
642 | } |
643 | #[inline] |
644 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
645 | // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. |
646 | unsafe { self.into_slice_range().get_unchecked_mut(slice) } |
647 | } |
648 | #[inline] |
649 | fn index(self, slice: &str) -> &Self::Output { |
650 | if *self.end() == usize::MAX { |
651 | str_index_overflow_fail(); |
652 | } |
653 | self.into_slice_range().index(slice) |
654 | } |
655 | #[inline] |
656 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
657 | if *self.end() == usize::MAX { |
658 | str_index_overflow_fail(); |
659 | } |
660 | self.into_slice_range().index_mut(slice) |
661 | } |
662 | } |
663 | |
664 | #[unstable(feature = "new_range_api", issue = "125687")] |
665 | unsafe impl SliceIndex<str> for range::RangeInclusive<usize> { |
666 | type Output = str; |
667 | #[inline] |
668 | fn get(self, slice: &str) -> Option<&Self::Output> { |
669 | if self.end == usize::MAX { None } else { self.into_slice_range().get(slice) } |
670 | } |
671 | #[inline] |
672 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
673 | if self.end == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } |
674 | } |
675 | #[inline] |
676 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
677 | // SAFETY: the caller must uphold the safety contract for `get_unchecked`. |
678 | unsafe { self.into_slice_range().get_unchecked(slice) } |
679 | } |
680 | #[inline] |
681 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
682 | // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. |
683 | unsafe { self.into_slice_range().get_unchecked_mut(slice) } |
684 | } |
685 | #[inline] |
686 | fn index(self, slice: &str) -> &Self::Output { |
687 | if self.end == usize::MAX { |
688 | str_index_overflow_fail(); |
689 | } |
690 | self.into_slice_range().index(slice) |
691 | } |
692 | #[inline] |
693 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
694 | if self.end == usize::MAX { |
695 | str_index_overflow_fail(); |
696 | } |
697 | self.into_slice_range().index_mut(slice) |
698 | } |
699 | } |
700 | |
701 | /// Implements substring slicing with syntax `&self[..= end]` or `&mut |
702 | /// self[..= end]`. |
703 | /// |
704 | /// Returns a slice of the given string from the byte range \[0, `end`\]. |
705 | /// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum |
706 | /// value for `usize`. |
707 | /// |
708 | /// This operation is *O*(1). |
709 | /// |
710 | /// # Panics |
711 | /// |
712 | /// Panics if `end` does not point to the ending byte offset of a character |
713 | /// (`end + 1` is either a starting byte offset as defined by |
714 | /// `is_char_boundary`, or equal to `len`), or if `end >= len`. |
715 | #[stable(feature = "inclusive_range", since = "1.26.0")] |
716 | unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> { |
717 | type Output = str; |
718 | #[inline] |
719 | fn get(self, slice: &str) -> Option<&Self::Output> { |
720 | (0..=self.end).get(slice) |
721 | } |
722 | #[inline] |
723 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
724 | (0..=self.end).get_mut(slice) |
725 | } |
726 | #[inline] |
727 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
728 | // SAFETY: the caller must uphold the safety contract for `get_unchecked`. |
729 | unsafe { (0..=self.end).get_unchecked(slice) } |
730 | } |
731 | #[inline] |
732 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
733 | // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. |
734 | unsafe { (0..=self.end).get_unchecked_mut(slice) } |
735 | } |
736 | #[inline] |
737 | fn index(self, slice: &str) -> &Self::Output { |
738 | (0..=self.end).index(slice) |
739 | } |
740 | #[inline] |
741 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
742 | (0..=self.end).index_mut(slice) |
743 | } |
744 | } |
745 | |
746 | /// Parse a value from a string |
747 | /// |
748 | /// `FromStr`'s [`from_str`] method is often used implicitly, through |
749 | /// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples. |
750 | /// |
751 | /// [`from_str`]: FromStr::from_str |
752 | /// [`parse`]: str::parse |
753 | /// |
754 | /// `FromStr` does not have a lifetime parameter, and so you can only parse types |
755 | /// that do not contain a lifetime parameter themselves. In other words, you can |
756 | /// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that |
757 | /// contains an `i32`, but not one that contains an `&i32`. |
758 | /// |
759 | /// # Input format and round-tripping |
760 | /// |
761 | /// The input format expected by a type's `FromStr` implementation depends on the type. Check the |
762 | /// type's documentation for the input formats it knows how to parse. Note that the input format of |
763 | /// a type's `FromStr` implementation might not necessarily accept the output format of its |
764 | /// `Display` implementation, and even if it does, the `Display` implementation may not be lossless |
765 | /// so the round-trip may lose information. |
766 | /// |
767 | /// However, if a type has a lossless `Display` implementation whose output is meant to be |
768 | /// conveniently machine-parseable and not just meant for human consumption, then the type may wish |
769 | /// to accept the same format in `FromStr`, and document that usage. Having both `Display` and |
770 | /// `FromStr` implementations where the result of `Display` cannot be parsed with `FromStr` may |
771 | /// surprise users. |
772 | /// |
773 | /// # Examples |
774 | /// |
775 | /// Basic implementation of `FromStr` on an example `Point` type: |
776 | /// |
777 | /// ``` |
778 | /// use std::str::FromStr; |
779 | /// |
780 | /// #[derive(Debug, PartialEq)] |
781 | /// struct Point { |
782 | /// x: i32, |
783 | /// y: i32 |
784 | /// } |
785 | /// |
786 | /// #[derive(Debug, PartialEq, Eq)] |
787 | /// struct ParsePointError; |
788 | /// |
789 | /// impl FromStr for Point { |
790 | /// type Err = ParsePointError; |
791 | /// |
792 | /// fn from_str(s: &str) -> Result<Self, Self::Err> { |
793 | /// let (x, y) = s |
794 | /// .strip_prefix('(') |
795 | /// .and_then(|s| s.strip_suffix(')')) |
796 | /// .and_then(|s| s.split_once(',')) |
797 | /// .ok_or(ParsePointError)?; |
798 | /// |
799 | /// let x_fromstr = x.parse::<i32>().map_err(|_| ParsePointError)?; |
800 | /// let y_fromstr = y.parse::<i32>().map_err(|_| ParsePointError)?; |
801 | /// |
802 | /// Ok(Point { x: x_fromstr, y: y_fromstr }) |
803 | /// } |
804 | /// } |
805 | /// |
806 | /// let expected = Ok(Point { x: 1, y: 2 }); |
807 | /// // Explicit call |
808 | /// assert_eq!(Point::from_str("(1,2)"), expected); |
809 | /// // Implicit calls, through parse |
810 | /// assert_eq!("(1,2)".parse(), expected); |
811 | /// assert_eq!("(1,2)".parse::<Point>(), expected); |
812 | /// // Invalid input string |
813 | /// assert!(Point::from_str("(1 2)").is_err()); |
814 | /// ``` |
815 | #[stable(feature = "rust1", since = "1.0.0")] |
816 | pub trait FromStr: Sized { |
817 | /// The associated error which can be returned from parsing. |
818 | #[stable(feature = "rust1", since = "1.0.0")] |
819 | type Err; |
820 | |
821 | /// Parses a string `s` to return a value of this type. |
822 | /// |
823 | /// If parsing succeeds, return the value inside [`Ok`], otherwise |
824 | /// when the string is ill-formatted return an error specific to the |
825 | /// inside [`Err`]. The error type is specific to the implementation of the trait. |
826 | /// |
827 | /// # Examples |
828 | /// |
829 | /// Basic usage with [`i32`], a type that implements `FromStr`: |
830 | /// |
831 | /// ``` |
832 | /// use std::str::FromStr; |
833 | /// |
834 | /// let s = "5"; |
835 | /// let x = i32::from_str(s).unwrap(); |
836 | /// |
837 | /// assert_eq!(5, x); |
838 | /// ``` |
839 | #[stable(feature = "rust1", since = "1.0.0")] |
840 | #[rustc_diagnostic_item= "from_str_method"] |
841 | fn from_str(s: &str) -> Result<Self, Self::Err>; |
842 | } |
843 | |
844 | #[stable(feature = "rust1", since = "1.0.0")] |
845 | impl FromStr for bool { |
846 | type Err = ParseBoolError; |
847 | |
848 | /// Parse a `bool` from a string. |
849 | /// |
850 | /// The only accepted values are `"true"` and `"false"`. Any other input |
851 | /// will return an error. |
852 | /// |
853 | /// # Examples |
854 | /// |
855 | /// ``` |
856 | /// use std::str::FromStr; |
857 | /// |
858 | /// assert_eq!(FromStr::from_str("true"), Ok(true)); |
859 | /// assert_eq!(FromStr::from_str("false"), Ok(false)); |
860 | /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err()); |
861 | /// ``` |
862 | /// |
863 | /// Note, in many cases, the `.parse()` method on `str` is more proper. |
864 | /// |
865 | /// ``` |
866 | /// assert_eq!("true".parse(), Ok(true)); |
867 | /// assert_eq!("false".parse(), Ok(false)); |
868 | /// assert!("not even a boolean".parse::<bool>().is_err()); |
869 | /// ``` |
870 | #[inline] |
871 | fn from_str(s: &str) -> Result<bool, ParseBoolError> { |
872 | match s { |
873 | "true"=> Ok(true), |
874 | "false"=> Ok(false), |
875 | _ => Err(ParseBoolError), |
876 | } |
877 | } |
878 | } |
879 |
Definitions
- cmp
- eq
- partial_cmp
- Output
- index
- index_mut
- str_index_overflow_fail
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- Output
- get
- get_mut
- get_unchecked
- get_unchecked_mut
- index
- index_mut
- FromStr
- Err
- from_str
- Err
Learn Rust with the experts
Find out more