1 | //! Trait implementations for `str`. |
2 | |
3 | use crate::cmp::Ordering; |
4 | use crate::intrinsics::unchecked_sub; |
5 | use crate::ops; |
6 | use crate::ptr; |
7 | use crate::slice::SliceIndex; |
8 | use crate::ub_checks::assert_unsafe_precondition; |
9 | |
10 | use super::ParseBoolError; |
11 | |
12 | /// Implements ordering of strings. |
13 | /// |
14 | /// Strings are ordered [lexicographically](Ord#lexicographical-comparison) by their byte values. This orders Unicode code |
15 | /// points based on their positions in the code charts. This is not necessarily the same as |
16 | /// "alphabetical" order, which varies by language and locale. Sorting strings according to |
17 | /// culturally-accepted standards requires locale-specific data that is outside the scope of |
18 | /// the `str` type. |
19 | #[stable (feature = "rust1" , since = "1.0.0" )] |
20 | impl Ord for str { |
21 | #[inline ] |
22 | fn cmp(&self, other: &str) -> Ordering { |
23 | self.as_bytes().cmp(other.as_bytes()) |
24 | } |
25 | } |
26 | |
27 | #[stable (feature = "rust1" , since = "1.0.0" )] |
28 | impl PartialEq for str { |
29 | #[inline ] |
30 | fn eq(&self, other: &str) -> bool { |
31 | self.as_bytes() == other.as_bytes() |
32 | } |
33 | } |
34 | |
35 | #[stable (feature = "rust1" , since = "1.0.0" )] |
36 | impl Eq for str {} |
37 | |
38 | /// 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" )] |
46 | impl PartialOrd for str { |
47 | #[inline ] |
48 | fn partial_cmp(&self, other: &str) -> Option<Ordering> { |
49 | Some(self.cmp(other)) |
50 | } |
51 | } |
52 | |
53 | #[stable (feature = "rust1" , since = "1.0.0" )] |
54 | impl<I> ops::Index<I> for str |
55 | where |
56 | I: SliceIndex<str>, |
57 | { |
58 | type Output = I::Output; |
59 | |
60 | #[inline ] |
61 | fn index(&self, index: I) -> &I::Output { |
62 | index.index(self) |
63 | } |
64 | } |
65 | |
66 | #[stable (feature = "rust1" , since = "1.0.0" )] |
67 | impl<I> ops::IndexMut<I> for str |
68 | where |
69 | I: SliceIndex<str>, |
70 | { |
71 | #[inline ] |
72 | fn index_mut(&mut self, index: I) -> &mut I::Output { |
73 | index.index_mut(self) |
74 | } |
75 | } |
76 | |
77 | #[inline (never)] |
78 | #[cold ] |
79 | #[track_caller ] |
80 | const fn str_index_overflow_fail() -> ! { |
81 | panic!("attempted to index str up to maximum usize" ); |
82 | } |
83 | |
84 | /// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`. |
85 | /// |
86 | /// Returns a slice of the whole string, i.e., returns `&self` or `&mut |
87 | /// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike |
88 | /// other indexing operations, this can never panic. |
89 | /// |
90 | /// This operation is *O*(1). |
91 | /// |
92 | /// Prior to 1.20.0, these indexing operations were still supported by |
93 | /// direct implementation of `Index` and `IndexMut`. |
94 | /// |
95 | /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. |
96 | #[stable (feature = "str_checked_slicing" , since = "1.20.0" )] |
97 | #[rustc_const_unstable (feature = "const_slice_index" , issue = "none" )] |
98 | unsafe impl SliceIndex<str> for ops::RangeFull { |
99 | type Output = str; |
100 | #[inline ] |
101 | fn get(self, slice: &str) -> Option<&Self::Output> { |
102 | Some(slice) |
103 | } |
104 | #[inline ] |
105 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
106 | Some(slice) |
107 | } |
108 | #[inline ] |
109 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
110 | slice |
111 | } |
112 | #[inline ] |
113 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
114 | slice |
115 | } |
116 | #[inline ] |
117 | fn index(self, slice: &str) -> &Self::Output { |
118 | slice |
119 | } |
120 | #[inline ] |
121 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
122 | slice |
123 | } |
124 | } |
125 | |
126 | /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut |
127 | /// self[begin .. end]`. |
128 | /// |
129 | /// Returns a slice of the given string from the byte range |
130 | /// [`begin`, `end`). |
131 | /// |
132 | /// This operation is *O*(1). |
133 | /// |
134 | /// Prior to 1.20.0, these indexing operations were still supported by |
135 | /// direct implementation of `Index` and `IndexMut`. |
136 | /// |
137 | /// # Panics |
138 | /// |
139 | /// Panics if `begin` or `end` does not point to the starting byte offset of |
140 | /// a character (as defined by `is_char_boundary`), if `begin > end`, or if |
141 | /// `end > len`. |
142 | /// |
143 | /// # Examples |
144 | /// |
145 | /// ``` |
146 | /// let s = "Löwe 老虎 Léopard" ; |
147 | /// assert_eq!(&s[0 .. 1], "L" ); |
148 | /// |
149 | /// assert_eq!(&s[1 .. 9], "öwe 老" ); |
150 | /// |
151 | /// // these will panic: |
152 | /// // byte 2 lies within `ö`: |
153 | /// // &s[2 ..3]; |
154 | /// |
155 | /// // byte 8 lies within `老` |
156 | /// // &s[1 .. 8]; |
157 | /// |
158 | /// // byte 100 is outside the string |
159 | /// // &s[3 .. 100]; |
160 | /// ``` |
161 | #[stable (feature = "str_checked_slicing" , since = "1.20.0" )] |
162 | #[rustc_const_unstable (feature = "const_slice_index" , issue = "none" )] |
163 | unsafe 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 | |
196 | assert_unsafe_precondition!( |
197 | // We'd like to check that the bounds are on char boundaries, |
198 | // but there's not really a way to do so without reading |
199 | // behind the pointer, which has aliasing implications. |
200 | // It's also not possible to move this check up to |
201 | // `str::get_unchecked` without adding a special function |
202 | // to `SliceIndex` just for this. |
203 | check_library_ub, |
204 | "str::get_unchecked requires that the range is within the string slice" , |
205 | ( |
206 | start: usize = self.start, |
207 | end: usize = self.end, |
208 | len: usize = slice.len() |
209 | ) => end >= start && end <= len, |
210 | ); |
211 | |
212 | // SAFETY: the caller guarantees that `self` is in bounds of `slice` |
213 | // which satisfies all the conditions for `add`. |
214 | unsafe { |
215 | let new_len = unchecked_sub(self.end, self.start); |
216 | ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str |
217 | } |
218 | } |
219 | #[inline ] |
220 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
221 | let slice = slice as *mut [u8]; |
222 | |
223 | assert_unsafe_precondition!( |
224 | check_library_ub, |
225 | "str::get_unchecked_mut requires that the range is within the string slice" , |
226 | ( |
227 | start: usize = self.start, |
228 | end: usize = self.end, |
229 | len: usize = slice.len() |
230 | ) => end >= start && end <= len, |
231 | ); |
232 | |
233 | // SAFETY: see comments for `get_unchecked`. |
234 | unsafe { |
235 | let new_len = unchecked_sub(self.end, self.start); |
236 | ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str |
237 | } |
238 | } |
239 | #[inline ] |
240 | fn index(self, slice: &str) -> &Self::Output { |
241 | let (start, end) = (self.start, self.end); |
242 | match self.get(slice) { |
243 | Some(s) => s, |
244 | None => super::slice_error_fail(slice, start, end), |
245 | } |
246 | } |
247 | #[inline ] |
248 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
249 | // is_char_boundary checks that the index is in [0, .len()] |
250 | // cannot reuse `get` as above, because of NLL trouble |
251 | if self.start <= self.end |
252 | && slice.is_char_boundary(self.start) |
253 | && slice.is_char_boundary(self.end) |
254 | { |
255 | // SAFETY: just checked that `start` and `end` are on a char boundary, |
256 | // and we are passing in a safe reference, so the return value will also be one. |
257 | unsafe { &mut *self.get_unchecked_mut(slice) } |
258 | } else { |
259 | super::slice_error_fail(slice, self.start, self.end) |
260 | } |
261 | } |
262 | } |
263 | |
264 | /// Implements substring slicing for arbitrary bounds. |
265 | /// |
266 | /// Returns a slice of the given string bounded by the byte indices |
267 | /// provided by each bound. |
268 | /// |
269 | /// This operation is *O*(1). |
270 | /// |
271 | /// # Panics |
272 | /// |
273 | /// Panics if `begin` or `end` (if it exists and once adjusted for |
274 | /// inclusion/exclusion) does not point to the starting byte offset of |
275 | /// a character (as defined by `is_char_boundary`), if `begin > end`, or if |
276 | /// `end > len`. |
277 | #[stable (feature = "slice_index_str_with_ops_bound_pair" , since = "1.73.0" )] |
278 | unsafe impl SliceIndex<str> for (ops::Bound<usize>, ops::Bound<usize>) { |
279 | type Output = str; |
280 | |
281 | #[inline ] |
282 | fn get(self, slice: &str) -> Option<&str> { |
283 | crate::slice::index::into_range(slice.len(), self)?.get(slice) |
284 | } |
285 | |
286 | #[inline ] |
287 | fn get_mut(self, slice: &mut str) -> Option<&mut str> { |
288 | crate::slice::index::into_range(slice.len(), self)?.get_mut(slice) |
289 | } |
290 | |
291 | #[inline ] |
292 | unsafe fn get_unchecked(self, slice: *const str) -> *const str { |
293 | let len = (slice as *const [u8]).len(); |
294 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
295 | unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked(slice) } |
296 | } |
297 | |
298 | #[inline ] |
299 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut str { |
300 | let len = (slice as *mut [u8]).len(); |
301 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
302 | unsafe { crate::slice::index::into_range_unchecked(len, self).get_unchecked_mut(slice) } |
303 | } |
304 | |
305 | #[inline ] |
306 | fn index(self, slice: &str) -> &str { |
307 | crate::slice::index::into_slice_range(slice.len(), self).index(slice) |
308 | } |
309 | |
310 | #[inline ] |
311 | fn index_mut(self, slice: &mut str) -> &mut str { |
312 | crate::slice::index::into_slice_range(slice.len(), self).index_mut(slice) |
313 | } |
314 | } |
315 | |
316 | /// Implements substring slicing with syntax `&self[.. end]` or `&mut |
317 | /// self[.. end]`. |
318 | /// |
319 | /// Returns a slice of the given string from the byte range \[0, `end`). |
320 | /// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`. |
321 | /// |
322 | /// This operation is *O*(1). |
323 | /// |
324 | /// Prior to 1.20.0, these indexing operations were still supported by |
325 | /// direct implementation of `Index` and `IndexMut`. |
326 | /// |
327 | /// # Panics |
328 | /// |
329 | /// Panics if `end` does not point to the starting byte offset of a |
330 | /// character (as defined by `is_char_boundary`), or if `end > len`. |
331 | #[stable (feature = "str_checked_slicing" , since = "1.20.0" )] |
332 | #[rustc_const_unstable (feature = "const_slice_index" , issue = "none" )] |
333 | unsafe impl SliceIndex<str> for ops::RangeTo<usize> { |
334 | type Output = str; |
335 | #[inline ] |
336 | fn get(self, slice: &str) -> Option<&Self::Output> { |
337 | if slice.is_char_boundary(self.end) { |
338 | // SAFETY: just checked that `end` is on a char boundary, |
339 | // and we are passing in a safe reference, so the return value will also be one. |
340 | Some(unsafe { &*self.get_unchecked(slice) }) |
341 | } else { |
342 | None |
343 | } |
344 | } |
345 | #[inline ] |
346 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
347 | if slice.is_char_boundary(self.end) { |
348 | // SAFETY: just checked that `end` is on a char boundary, |
349 | // and we are passing in a safe reference, so the return value will also be one. |
350 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
351 | } else { |
352 | None |
353 | } |
354 | } |
355 | #[inline ] |
356 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
357 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
358 | unsafe { (0..self.end).get_unchecked(slice) } |
359 | } |
360 | #[inline ] |
361 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
362 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
363 | unsafe { (0..self.end).get_unchecked_mut(slice) } |
364 | } |
365 | #[inline ] |
366 | fn index(self, slice: &str) -> &Self::Output { |
367 | let end = self.end; |
368 | match self.get(slice) { |
369 | Some(s) => s, |
370 | None => super::slice_error_fail(slice, 0, end), |
371 | } |
372 | } |
373 | #[inline ] |
374 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
375 | if slice.is_char_boundary(self.end) { |
376 | // SAFETY: just checked that `end` 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) } |
379 | } else { |
380 | super::slice_error_fail(slice, 0, self.end) |
381 | } |
382 | } |
383 | } |
384 | |
385 | /// Implements substring slicing with syntax `&self[begin ..]` or `&mut |
386 | /// self[begin ..]`. |
387 | /// |
388 | /// Returns a slice of the given string from the byte range \[`begin`, `len`). |
389 | /// Equivalent to `&self[begin .. len]` or `&mut self[begin .. len]`. |
390 | /// |
391 | /// This operation is *O*(1). |
392 | /// |
393 | /// Prior to 1.20.0, these indexing operations were still supported by |
394 | /// direct implementation of `Index` and `IndexMut`. |
395 | /// |
396 | /// # Panics |
397 | /// |
398 | /// Panics if `begin` does not point to the starting byte offset of |
399 | /// a character (as defined by `is_char_boundary`), or if `begin > len`. |
400 | #[stable (feature = "str_checked_slicing" , since = "1.20.0" )] |
401 | #[rustc_const_unstable (feature = "const_slice_index" , issue = "none" )] |
402 | unsafe impl SliceIndex<str> for ops::RangeFrom<usize> { |
403 | type Output = str; |
404 | #[inline ] |
405 | fn get(self, slice: &str) -> Option<&Self::Output> { |
406 | if slice.is_char_boundary(self.start) { |
407 | // SAFETY: just checked that `start` is on a char boundary, |
408 | // and we are passing in a safe reference, so the return value will also be one. |
409 | Some(unsafe { &*self.get_unchecked(slice) }) |
410 | } else { |
411 | None |
412 | } |
413 | } |
414 | #[inline ] |
415 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
416 | if slice.is_char_boundary(self.start) { |
417 | // SAFETY: just checked that `start` is on a char boundary, |
418 | // and we are passing in a safe reference, so the return value will also be one. |
419 | Some(unsafe { &mut *self.get_unchecked_mut(slice) }) |
420 | } else { |
421 | None |
422 | } |
423 | } |
424 | #[inline ] |
425 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
426 | let len = (slice as *const [u8]).len(); |
427 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
428 | unsafe { (self.start..len).get_unchecked(slice) } |
429 | } |
430 | #[inline ] |
431 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
432 | let len = (slice as *mut [u8]).len(); |
433 | // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
434 | unsafe { (self.start..len).get_unchecked_mut(slice) } |
435 | } |
436 | #[inline ] |
437 | fn index(self, slice: &str) -> &Self::Output { |
438 | let (start, end) = (self.start, slice.len()); |
439 | match self.get(slice) { |
440 | Some(s) => s, |
441 | None => super::slice_error_fail(slice, start, end), |
442 | } |
443 | } |
444 | #[inline ] |
445 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
446 | if slice.is_char_boundary(self.start) { |
447 | // SAFETY: just checked that `start` is on a char boundary, |
448 | // and we are passing in a safe reference, so the return value will also be one. |
449 | unsafe { &mut *self.get_unchecked_mut(slice) } |
450 | } else { |
451 | super::slice_error_fail(slice, self.start, slice.len()) |
452 | } |
453 | } |
454 | } |
455 | |
456 | /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut |
457 | /// self[begin ..= end]`. |
458 | /// |
459 | /// Returns a slice of the given string from the byte range |
460 | /// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut |
461 | /// self[begin .. end + 1]`, except if `end` has the maximum value for |
462 | /// `usize`. |
463 | /// |
464 | /// This operation is *O*(1). |
465 | /// |
466 | /// # Panics |
467 | /// |
468 | /// Panics if `begin` does not point to the starting byte offset of |
469 | /// a character (as defined by `is_char_boundary`), if `end` does not point |
470 | /// to the ending byte offset of a character (`end + 1` is either a starting |
471 | /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. |
472 | #[stable (feature = "inclusive_range" , since = "1.26.0" )] |
473 | #[rustc_const_unstable (feature = "const_slice_index" , issue = "none" )] |
474 | unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> { |
475 | type Output = str; |
476 | #[inline ] |
477 | fn get(self, slice: &str) -> Option<&Self::Output> { |
478 | if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) } |
479 | } |
480 | #[inline ] |
481 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
482 | if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } |
483 | } |
484 | #[inline ] |
485 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
486 | // SAFETY: the caller must uphold the safety contract for `get_unchecked`. |
487 | unsafe { self.into_slice_range().get_unchecked(slice) } |
488 | } |
489 | #[inline ] |
490 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
491 | // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. |
492 | unsafe { self.into_slice_range().get_unchecked_mut(slice) } |
493 | } |
494 | #[inline ] |
495 | fn index(self, slice: &str) -> &Self::Output { |
496 | if *self.end() == usize::MAX { |
497 | str_index_overflow_fail(); |
498 | } |
499 | self.into_slice_range().index(slice) |
500 | } |
501 | #[inline ] |
502 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
503 | if *self.end() == usize::MAX { |
504 | str_index_overflow_fail(); |
505 | } |
506 | self.into_slice_range().index_mut(slice) |
507 | } |
508 | } |
509 | |
510 | /// Implements substring slicing with syntax `&self[..= end]` or `&mut |
511 | /// self[..= end]`. |
512 | /// |
513 | /// Returns a slice of the given string from the byte range \[0, `end`\]. |
514 | /// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum |
515 | /// value for `usize`. |
516 | /// |
517 | /// This operation is *O*(1). |
518 | /// |
519 | /// # Panics |
520 | /// |
521 | /// Panics if `end` does not point to the ending byte offset of a character |
522 | /// (`end + 1` is either a starting byte offset as defined by |
523 | /// `is_char_boundary`, or equal to `len`), or if `end >= len`. |
524 | #[stable (feature = "inclusive_range" , since = "1.26.0" )] |
525 | #[rustc_const_unstable (feature = "const_slice_index" , issue = "none" )] |
526 | unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> { |
527 | type Output = str; |
528 | #[inline ] |
529 | fn get(self, slice: &str) -> Option<&Self::Output> { |
530 | (0..=self.end).get(slice) |
531 | } |
532 | #[inline ] |
533 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { |
534 | (0..=self.end).get_mut(slice) |
535 | } |
536 | #[inline ] |
537 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { |
538 | // SAFETY: the caller must uphold the safety contract for `get_unchecked`. |
539 | unsafe { (0..=self.end).get_unchecked(slice) } |
540 | } |
541 | #[inline ] |
542 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { |
543 | // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. |
544 | unsafe { (0..=self.end).get_unchecked_mut(slice) } |
545 | } |
546 | #[inline ] |
547 | fn index(self, slice: &str) -> &Self::Output { |
548 | (0..=self.end).index(slice) |
549 | } |
550 | #[inline ] |
551 | fn index_mut(self, slice: &mut str) -> &mut Self::Output { |
552 | (0..=self.end).index_mut(slice) |
553 | } |
554 | } |
555 | |
556 | /// Parse a value from a string |
557 | /// |
558 | /// `FromStr`'s [`from_str`] method is often used implicitly, through |
559 | /// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples. |
560 | /// |
561 | /// [`from_str`]: FromStr::from_str |
562 | /// [`parse`]: str::parse |
563 | /// |
564 | /// `FromStr` does not have a lifetime parameter, and so you can only parse types |
565 | /// that do not contain a lifetime parameter themselves. In other words, you can |
566 | /// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that |
567 | /// contains an `i32`, but not one that contains an `&i32`. |
568 | /// |
569 | /// # Examples |
570 | /// |
571 | /// Basic implementation of `FromStr` on an example `Point` type: |
572 | /// |
573 | /// ``` |
574 | /// use std::str::FromStr; |
575 | /// |
576 | /// #[derive(Debug, PartialEq)] |
577 | /// struct Point { |
578 | /// x: i32, |
579 | /// y: i32 |
580 | /// } |
581 | /// |
582 | /// #[derive(Debug, PartialEq, Eq)] |
583 | /// struct ParsePointError; |
584 | /// |
585 | /// impl FromStr for Point { |
586 | /// type Err = ParsePointError; |
587 | /// |
588 | /// fn from_str(s: &str) -> Result<Self, Self::Err> { |
589 | /// let (x, y) = s |
590 | /// .strip_prefix('(' ) |
591 | /// .and_then(|s| s.strip_suffix(')' )) |
592 | /// .and_then(|s| s.split_once(',' )) |
593 | /// .ok_or(ParsePointError)?; |
594 | /// |
595 | /// let x_fromstr = x.parse::<i32>().map_err(|_| ParsePointError)?; |
596 | /// let y_fromstr = y.parse::<i32>().map_err(|_| ParsePointError)?; |
597 | /// |
598 | /// Ok(Point { x: x_fromstr, y: y_fromstr }) |
599 | /// } |
600 | /// } |
601 | /// |
602 | /// let expected = Ok(Point { x: 1, y: 2 }); |
603 | /// // Explicit call |
604 | /// assert_eq!(Point::from_str("(1,2)" ), expected); |
605 | /// // Implicit calls, through parse |
606 | /// assert_eq!("(1,2)" .parse(), expected); |
607 | /// assert_eq!("(1,2)" .parse::<Point>(), expected); |
608 | /// // Invalid input string |
609 | /// assert!(Point::from_str("(1 2)" ).is_err()); |
610 | /// ``` |
611 | #[stable (feature = "rust1" , since = "1.0.0" )] |
612 | pub trait FromStr: Sized { |
613 | /// The associated error which can be returned from parsing. |
614 | #[stable (feature = "rust1" , since = "1.0.0" )] |
615 | type Err; |
616 | |
617 | /// Parses a string `s` to return a value of this type. |
618 | /// |
619 | /// If parsing succeeds, return the value inside [`Ok`], otherwise |
620 | /// when the string is ill-formatted return an error specific to the |
621 | /// inside [`Err`]. The error type is specific to the implementation of the trait. |
622 | /// |
623 | /// # Examples |
624 | /// |
625 | /// Basic usage with [`i32`], a type that implements `FromStr`: |
626 | /// |
627 | /// ``` |
628 | /// use std::str::FromStr; |
629 | /// |
630 | /// let s = "5" ; |
631 | /// let x = i32::from_str(s).unwrap(); |
632 | /// |
633 | /// assert_eq!(5, x); |
634 | /// ``` |
635 | #[stable (feature = "rust1" , since = "1.0.0" )] |
636 | #[rustc_diagnostic_item = "from_str_method" ] |
637 | fn from_str(s: &str) -> Result<Self, Self::Err>; |
638 | } |
639 | |
640 | #[stable (feature = "rust1" , since = "1.0.0" )] |
641 | impl FromStr for bool { |
642 | type Err = ParseBoolError; |
643 | |
644 | /// Parse a `bool` from a string. |
645 | /// |
646 | /// The only accepted values are `"true"` and `"false"`. Any other input |
647 | /// will return an error. |
648 | /// |
649 | /// # Examples |
650 | /// |
651 | /// ``` |
652 | /// use std::str::FromStr; |
653 | /// |
654 | /// assert_eq!(FromStr::from_str("true" ), Ok(true)); |
655 | /// assert_eq!(FromStr::from_str("false" ), Ok(false)); |
656 | /// assert!(<bool as FromStr>::from_str("not even a boolean" ).is_err()); |
657 | /// ``` |
658 | /// |
659 | /// Note, in many cases, the `.parse()` method on `str` is more proper. |
660 | /// |
661 | /// ``` |
662 | /// assert_eq!("true" .parse(), Ok(true)); |
663 | /// assert_eq!("false" .parse(), Ok(false)); |
664 | /// assert!("not even a boolean" .parse::<bool>().is_err()); |
665 | /// ``` |
666 | #[inline ] |
667 | fn from_str(s: &str) -> Result<bool, ParseBoolError> { |
668 | match s { |
669 | "true" => Ok(true), |
670 | "false" => Ok(false), |
671 | _ => Err(ParseBoolError), |
672 | } |
673 | } |
674 | } |
675 | |