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