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
131
132
133
134
135
136
137
138
139
140
141
142
//! 转换为整数类型的错误类型。

use crate::convert::Infallible;
use crate::error::Error;
use crate::fmt;

/// 当检查的整数类型转换失败时,返回错误类型。
#[stable(feature = "try_from", since = "1.34.0")]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct TryFromIntError(pub(crate) ());

#[stable(feature = "try_from", since = "1.34.0")]
impl fmt::Display for TryFromIntError {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        #[allow(deprecated)]
        self.description().fmt(fmt)
    }
}

#[stable(feature = "try_from", since = "1.34.0")]
impl Error for TryFromIntError {
    #[allow(deprecated)]
    fn description(&self) -> &str {
        "out of range integral type conversion attempted"
    }
}

#[stable(feature = "try_from", since = "1.34.0")]
impl From<Infallible> for TryFromIntError {
    fn from(x: Infallible) -> TryFromIntError {
        match x {}
    }
}

#[unstable(feature = "never_type", issue = "35121")]
impl From<!> for TryFromIntError {
    #[inline]
    fn from(never: !) -> TryFromIntError {
        // 匹配而不是强制,以确保当 `Infallible` 成为 `!` 的别名时,上述 `From<Infallible> for TryFromIntError` 这样的代码将继续起作用。
        //
        //
        match never {}
    }
}

/// 解析整数时可以返回的错误。
///
/// 此错误用作原始整数类型 (例如 [`i8::from_str_radix`]) 上 `from_str_radix()` 函数的错误类型。
///
/// # 潜在原因
///
/// 除其他原因外,例如,当从标准输入中获取 `ParseIntError` 时,可能会由于字符串中的前导或尾随空格而抛出 `ParseIntError`。
///
/// 使用 [`str::trim()`] 方法可确保在解析之前不留空格。
///
/// # Example
///
/// ```
/// if let Err(e) = i32::from_str_radix("a12", 10) {
///     println!("Failed conversion to i32: {e}");
/// }
/// ```
///
#[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseIntError {
    pub(super) kind: IntErrorKind,
}

/// 枚举存储各种类型的错误,这些错误可能导致解析整数失败。
///
/// # Example
///
/// ```
/// # fn main() {
/// if let Err(e) = i32::from_str_radix("a12", 10) {
///     println!("Failed conversion to i32: {:?}", e.kind());
/// }
/// # }
/// ```
#[stable(feature = "int_error_matching", since = "1.55.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum IntErrorKind {
    /// 被解析的值是空的。
    ///
    /// 解析空字符串时将创建此变体。
    #[stable(feature = "int_error_matching", since = "1.55.0")]
    Empty,
    /// 在其上下文中包含无效数字。
    ///
    /// 除其他原因外,当解析包含非 ASCII 字符的字符串时,将创建这个变体。
    ///
    /// 当 `+` 或 `-` 单独放置在字符串中或放置在数字中间时,也会创建此变体。
    ///
    ///
    #[stable(feature = "int_error_matching", since = "1.55.0")]
    InvalidDigit,
    /// 整数太大,无法存储为目标整数类型。
    #[stable(feature = "int_error_matching", since = "1.55.0")]
    PosOverflow,
    /// 整数太小,无法存储为目标整数类型。
    #[stable(feature = "int_error_matching", since = "1.55.0")]
    NegOverflow,
    /// 值为零
    ///
    /// 当解析字符串的值为零时,将发出此变体,这对于非零类型是非法的。
    ///
    #[stable(feature = "int_error_matching", since = "1.55.0")]
    Zero,
}

impl ParseIntError {
    /// 输出解析整数失败的详细原因。
    #[must_use]
    #[stable(feature = "int_error_matching", since = "1.55.0")]
    pub fn kind(&self) -> &IntErrorKind {
        &self.kind
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for ParseIntError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        #[allow(deprecated)]
        self.description().fmt(f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Error for ParseIntError {
    #[allow(deprecated)]
    fn description(&self) -> &str {
        match self.kind {
            IntErrorKind::Empty => "cannot parse integer from empty string",
            IntErrorKind::InvalidDigit => "invalid digit found in string",
            IntErrorKind::PosOverflow => "number too large to fit in target type",
            IntErrorKind::NegOverflow => "number too small to fit in target type",
            IntErrorKind::Zero => "number would be zero for non-zero type",
        }
    }
}