1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
//! 定义 utf8 错误类型。 use crate::fmt; /// 尝试将 [`u8`] 的序列解释为字符串时可能发生的错误。 /// /// 这样,例如 [`String`] 和 [`&str`] 的 `from_utf8` 系列函数和方法都利用了此错误。 /// /// [`String`]: ../../std/string/struct.String.html#method.from_utf8 /// [`&str`]: super::from_utf8 /// /// # Examples /// /// 此错误类型的方法可用于创建类似于 `String::from_utf8_lossy` 的功能,而无需分配堆内存: /// /// /// ``` /// fn from_utf8_lossy<F>(mut input: &[u8], mut push: F) where F: FnMut(&str) { /// loop { /// match std::str::from_utf8(input) { /// Ok(valid) => { /// push(valid); /// break /// } /// Err(error) => { /// let (valid, after_valid) = input.split_at(error.valid_up_to()); /// unsafe { /// push(std::str::from_utf8_unchecked(valid)) /// } /// push("\u{FFFD}"); /// /// if let Some(invalid_sequence_length) = error.error_len() { /// input = &after_valid[invalid_sequence_length..] /// } else { /// break /// } /// } /// } /// } /// } /// ``` /// /// #[derive(Copy, Eq, PartialEq, Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Utf8Error { pub(super) valid_up_to: usize, pub(super) error_len: Option<u8>, } impl Utf8Error { /// 返回给定字符串中的索引,直到对其进行有效 UTF-8 验证为止。 /// /// 它是使 `from_utf8(&input[..index])` 返回 `Ok(_)` 的最大索引。 /// /// /// # Examples /// /// 基本用法: /// /// ``` /// use std::str; /// /// // vector 中的一些无效字节 /// let sparkle_heart = vec![0, 159, 146, 150]; /// /// // std::str::from_utf8 返回 Utf8Error /// let error = str::from_utf8(&sparkle_heart).unwrap_err(); /// /// // 第二个字节在这里无效 /// assert_eq!(1, error.valid_up_to()); /// ``` /// #[stable(feature = "utf8_error", since = "1.5.0")] #[inline] pub fn valid_up_to(&self) -> usize { self.valid_up_to } /// 提供有关失败的更多信息: /// /// * `None`: 输入的末尾意外到达。 /// `self.valid_up_to()` 从输入末尾开始是 1 到 3 个字节。 /// 如果字节流 (例如文件或网络套接字) 正在以增量方式进行解码,则这可能是有效的 `char`,其 UTF-8 字节序列跨越了多个块。 /// /// /// * `Some(len)`: 遇到意外的字节。 /// 提供的长度是从 `valid_up_to()` 给定的索引处开始的无效字节序列的长度。 /// 如果有损解码,则应在该序列之后 (插入 [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] 之后) 恢复解码。 /// /// [U+FFFD]: ../../std/char/constant.REPLACEMENT_CHARACTER.html /// /// /// #[stable(feature = "utf8_error_error_len", since = "1.20.0")] #[inline] pub fn error_len(&self) -> Option<usize> { self.error_len.map(|len| len as usize) } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for Utf8Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(error_len) = self.error_len { write!( f, "invalid utf-8 sequence of {} bytes from index {}", error_len, self.valid_up_to ) } else { write!(f, "incomplete utf-8 byte sequence from index {}", self.valid_up_to) } } } /// 使用 [`from_str`] 解析 `bool` 失败时返回错误 /// /// [`from_str`]: super::FromStr::from_str #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] #[stable(feature = "rust1", since = "1.0.0")] pub struct ParseBoolError; #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for ParseBoolError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { "provided string was not `true` or `false`".fmt(f) } }