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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
//! 对 ASCII 字符串和字符的操作。
//!
//! Rust 中的大多数字符串操作都作用于 UTF-8 字符串。
//! 但是,有时只考虑针对特定操作的 ASCII 字符集更有意义。
//!
//! [`AsciiExt`] trait 提供了允许仅对 ASCII 子集起作用而仅使非 ASCII 字符不起作用的字符操作的方法。
//!
//!
//! [`escape_default`] 函数在给定字符的转义版本的字节上提供迭代器。
//!
//!
//!

#![stable(feature = "rust1", since = "1.0.0")]

#[stable(feature = "rust1", since = "1.0.0")]
pub use core::ascii::{escape_default, EscapeDefault};

#[unstable(feature = "ascii_char", issue = "110998")]
pub use core::ascii::Char;

/// 仅 ASCII 子集操作的扩展方法。
///
/// 请注意,对看似非 ASCII 字符的操作有时会产生意外结果。考虑以下示例:
///
/// ```
/// use std::ascii::AsciiExt;
///
/// assert_eq!(AsciiExt::to_ascii_uppercase("café"), "CAFÉ");
/// assert_eq!(AsciiExt::to_ascii_uppercase("café"), "CAFé");
/// ```
///
/// 在第一个示例中,小写的字符串表示为 `"cafe\u{301}"` (最后一个字符为重音符 [组合字符][combining character])。与字符串中的其他字符不同,组合字符不会映射到大写变体,从而导致 `"CAFE\u{301}"`。在第二个示例中,小写的字符串表示为 `"caf\u{e9}"` (最后一个字符是单个 Unicode 字符,表示带有尖音的 'e')。
///
/// 由于最后一个字符是在 ASCII 的作用域之外定义的,因此它不会被映射到大写变体,从而导致 `"CAF\u{e9}"`。
///
/// [combining character]: https://en.wikipedia.org/wiki/Combining_character
///
///
///
///
///
///
#[stable(feature = "rust1", since = "1.0.0")]
#[deprecated(since = "1.26.0", note = "use inherent methods instead")]
pub trait AsciiExt {
    /// 复制的 ASCII 字符的容器类型。
    #[stable(feature = "rust1", since = "1.0.0")]
    type Owned;

    /// 检查该值是否在 ASCII 范围内。
    ///
    /// # Note
    ///
    /// 不推荐使用此方法,而推荐使用 `u8`,`char`,`[u8]` 和 `str` 上相同名称的固有方法。
    ///
    #[stable(feature = "rust1", since = "1.0.0")]
    fn is_ascii(&self) -> bool;

    /// 使值的副本等效于其 ASCII 大写字母。
    ///
    /// ASCII 字母 'a' 到 'z' 映射到 'A' 到 'Z',但是非 ASCII 字母不变。
    ///
    /// 要就地将值大写,请使用 [`make_ascii_uppercase`]。
    ///
    /// 要除非 ASCII 字符外还使用大写 ASCII 字符,请使用 [`str::to_uppercase`]。
    ///
    /// # Note
    ///
    /// 不推荐使用此方法,而推荐使用 `u8`,`char`,`[u8]` 和 `str` 上相同名称的固有方法。
    ///
    ///
    /// [`make_ascii_uppercase`]: AsciiExt::make_ascii_uppercase
    ///
    ///
    #[stable(feature = "rust1", since = "1.0.0")]
    #[allow(deprecated)]
    fn to_ascii_uppercase(&self) -> Self::Owned;

    /// 以等效的 ASCII 小写形式复制值。
    ///
    /// ASCII 字母 'A' 到 'Z' 映射到 'a' 到 'z',但是非 ASCII 字母不变。
    ///
    /// 要就地小写该值,请使用 [`make_ascii_lowercase`]。
    ///
    /// 要除非 ASCII 字符外还使用小写 ASCII 字符,请使用 [`str::to_lowercase`]。
    ///
    /// # Note
    ///
    /// 不推荐使用此方法,而推荐使用 `u8`,`char`,`[u8]` 和 `str` 上相同名称的固有方法。
    ///
    ///
    /// [`make_ascii_lowercase`]: AsciiExt::make_ascii_lowercase
    ///
    ///
    #[stable(feature = "rust1", since = "1.0.0")]
    #[allow(deprecated)]
    fn to_ascii_lowercase(&self) -> Self::Owned;

    /// 检查两个值是否为 ASCII 不区分大小写的匹配。
    ///
    /// 与 `to_ascii_lowercase(a) == to_ascii_lowercase(b)` 相同,但不分配和复制临时文件。
    ///
    /// # Note
    ///
    /// 不推荐使用此方法,而推荐使用 `u8`,`char`,`[u8]` 和 `str` 上相同名称的固有方法。
    ///
    ///
    #[stable(feature = "rust1", since = "1.0.0")]
    fn eq_ignore_ascii_case(&self, other: &Self) -> bool;

    /// 将此类型就地转换为其 ASCII 大写等效项。
    ///
    /// ASCII 字母 'a' 到 'z' 映射到 'A' 到 'Z',但是非 ASCII 字母不变。
    ///
    /// 要返回新的大写值而不修改现有值,请使用 [`to_ascii_uppercase`]。
    ///
    /// # Note
    ///
    /// 不推荐使用此方法,而推荐使用 `u8`,`char`,`[u8]` 和 `str` 上相同名称的固有方法。
    ///
    ///
    /// [`to_ascii_uppercase`]: AsciiExt::to_ascii_uppercase
    ///
    ///
    #[stable(feature = "ascii", since = "1.9.0")]
    fn make_ascii_uppercase(&mut self);

    /// 将此类型就地转换为其 ASCII 小写等效项。
    ///
    /// ASCII 字母 'A' 到 'Z' 映射到 'a' 到 'z',但是非 ASCII 字母不变。
    ///
    /// 要返回新的小写值而不修改现有值,请使用 [`to_ascii_lowercase`]。
    ///
    /// # Note
    ///
    /// 不推荐使用此方法,而推荐使用 `u8`,`char`,`[u8]` 和 `str` 上相同名称的固有方法。
    ///
    ///
    /// [`to_ascii_lowercase`]: AsciiExt::to_ascii_lowercase
    ///
    ///
    #[stable(feature = "ascii", since = "1.9.0")]
    fn make_ascii_lowercase(&mut self);
}

macro_rules! delegating_ascii_methods {
    () => {
        #[inline]
        fn is_ascii(&self) -> bool {
            self.is_ascii()
        }

        #[inline]
        fn to_ascii_uppercase(&self) -> Self::Owned {
            self.to_ascii_uppercase()
        }

        #[inline]
        fn to_ascii_lowercase(&self) -> Self::Owned {
            self.to_ascii_lowercase()
        }

        #[inline]
        fn eq_ignore_ascii_case(&self, o: &Self) -> bool {
            self.eq_ignore_ascii_case(o)
        }

        #[inline]
        fn make_ascii_uppercase(&mut self) {
            self.make_ascii_uppercase();
        }

        #[inline]
        fn make_ascii_lowercase(&mut self) {
            self.make_ascii_lowercase();
        }
    };
}

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsciiExt for u8 {
    type Owned = u8;

    delegating_ascii_methods!();
}

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsciiExt for char {
    type Owned = char;

    delegating_ascii_methods!();
}

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsciiExt for [u8] {
    type Owned = Vec<u8>;

    delegating_ascii_methods!();
}

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsciiExt for str {
    type Owned = String;

    delegating_ascii_methods!();
}