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)
    }
}