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
//! 该模块包含用于处理 16 位字符 (UCS-2 或 UTF-16) 的结构
#![allow(dead_code)]

use crate::marker::PhantomData;
use crate::num::NonZeroU16;
use crate::ptr::NonNull;

/// LPWSTR 上的安全迭代器 (又名指向以 NULL 结尾的一系列 UTF-16 代码单元的指针)。
///
pub struct WStrUnits<'a> {
    // 指针绝不能为空...
    lpwstr: NonNull<u16>,
    // ...并且它指向的内存必须在这个生命周期间有效。
    lifetime: PhantomData<&'a [u16]>,
}

impl WStrUnits<'_> {
    /// 创建迭代器。如果 `lpwstr` 为空,则返回 `None`。
    ///
    /// SAFETY: `lpwstr` 必须指向一个以空字符结尾的宽字符串,该字符串至少与此结构体的生命周期一样长。
    ///
    pub unsafe fn new(lpwstr: *const u16) -> Option<Self> {
        Some(Self { lpwstr: NonNull::new(lpwstr as _)?, lifetime: PhantomData })
    }

    pub fn peek(&self) -> Option<NonZeroU16> {
        // SAFETY: 读取当前的项总是安全的,因为我们永远不会移出数组的边界。
        //
        unsafe { NonZeroU16::new(*self.lpwstr.as_ptr()) }
    }

    /// 在 `predicate` 返回 true 时推进迭代器。
    /// 返回其前进的项数。
    pub fn advance_while<P: FnMut(NonZeroU16) -> bool>(&mut self, mut predicate: P) -> usize {
        let mut counter = 0;
        while let Some(w) = self.peek() {
            if !predicate(w) {
                break;
            }
            counter += 1;
            self.next();
        }
        counter
    }
}

impl Iterator for WStrUnits<'_> {
    // 这永远不会返回零,因为这标志着字符串的结尾。
    type Item = NonZeroU16;
    fn next(&mut self) -> Option<NonZeroU16> {
        // SAFETY: 如果达到 NULL,我们立即返回。
        // 因此,在那之后推进指针是安全的。
        unsafe {
            let next = self.peek()?;
            self.lpwstr = NonNull::new_unchecked(self.lpwstr.as_ptr().add(1));
            Some(next)
        }
    }
}