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
//! UTF-8 和 UTF-16 解码迭代器

use crate::error::Error;
use crate::fmt;

/// 一个迭代器,用于解码来自 u16 迭代器的 UTF-16 编码的代码点。
///
/// 这个 `struct` 是通过 [`char`] 上的 [`decode_utf16`] 方法创建的。
/// 有关更多信息,请参见其文档。
///
/// [`decode_utf16`]: char::decode_utf16
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[derive(Clone, Debug)]
pub struct DecodeUtf16<I>
where
    I: Iterator<Item = u16>,
{
    iter: I,
    buf: Option<u16>,
}

/// 解码 UTF-16 代码点时可以返回的错误。
///
/// 该 `struct` 是在使用 [`DecodeUtf16`] 类型时创建的。
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct DecodeUtf16Error {
    code: u16,
}

/// 在 `iter` 中的 UTF-16 编码的代码点上创建一个迭代器,将不成对的代理返回为 `Err`s。
/// 请参见 [`char::decode_utf16`]。
#[inline]
pub(super) fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
    DecodeUtf16 { iter: iter.into_iter(), buf: None }
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
    type Item = Result<char, DecodeUtf16Error>;

    fn next(&mut self) -> Option<Result<char, DecodeUtf16Error>> {
        let u = match self.buf.take() {
            Some(buf) => buf,
            None => self.iter.next()?,
        };

        if !u.is_utf16_surrogate() {
            // SAFETY: 不是代理
            Some(Ok(unsafe { char::from_u32_unchecked(u as u32) }))
        } else if u >= 0xDC00 {
            // 尾随代理
            Some(Err(DecodeUtf16Error { code: u }))
        } else {
            let u2 = match self.iter.next() {
                Some(u2) => u2,
                // eof
                None => return Some(Err(DecodeUtf16Error { code: u })),
            };
            if u2 < 0xDC00 || u2 > 0xDFFF {
                // 不是尾随的代理,因此我们不是有效的代理对,因此请回绕以在下一次重新编码 u2。
                //
                self.buf = Some(u2);
                return Some(Err(DecodeUtf16Error { code: u }));
            }

            // 一切正常,让我们对其进行解码。
            let c = (((u & 0x3ff) as u32) << 10 | (u2 & 0x3ff) as u32) + 0x1_0000;
            // SAFETY: 我们检查了这是合法的 unicode 值
            Some(Ok(unsafe { char::from_u32_unchecked(c) }))
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let (low, high) = self.iter.size_hint();

        let (low_buf, high_buf) = match self.buf {
            // buf 为空,其中没有其他元素。
            None => (0, 0),
            // `u` 是一个非代理,所以它总是一个附加字符。
            Some(u) if !u.is_utf16_surrogate() => (1, 1),
            // `u` 是一个前导代理 (它永远不能是一个尾随代理,并且由于前一个分支它是一个代理) 并且 `self.iter` 是空的。
            //
            //
            // `u` 不能配对,因为 `self.iter` 是空的,所以它总是会成为一个附加元素 (error)。
            //
            Some(_u) if high == Some(0) => (1, 1),
            // `u` 是一个前导代理,`iter` 可能是非空的。
            //
            // `u` 可以与尾随代理配对,在这种情况下不会产生额外的元素,或者它可能成为错误,在这种情况下它是一个额外的字符 (error)。
            //
            Some(_u) => (0, 1),
        };

        // `self.iter` 可以包含完全有效的代理 (每个字符 2 个元素),或完全非代理 (每个字符 1 个元素)。
        //
        //
        // 在奇数下界,至少一个元素必须保持不成对 (与 `self.iter` 中的其他元素),所以我们四舍五入。
        //
        let low = low.div_ceil(2) + low_buf;
        let high = high.and_then(|h| h.checked_add(high_buf));

        (low, high)
    }
}

impl DecodeUtf16Error {
    /// 返回导致此错误的未配对代理。
    #[must_use]
    #[stable(feature = "decode_utf16", since = "1.9.0")]
    pub fn unpaired_surrogate(&self) -> u16 {
        self.code
    }
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl fmt::Display for DecodeUtf16Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "unpaired surrogate found: {:x}", self.code)
    }
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl Error for DecodeUtf16Error {
    #[allow(deprecated)]
    fn description(&self) -> &str {
        "unpaired surrogate found"
    }
}