const_str/__ctfe/
is_ascii.rs

1pub struct IsAscii<T>(pub T);
2
3impl IsAscii<&[u8]> {
4    pub const fn const_eval(&self) -> bool {
5        let bytes = self.0;
6        let mut i = 0;
7        while i < bytes.len() {
8            if !bytes[i].is_ascii() {
9                return false;
10            }
11            i += 1;
12        }
13        true
14    }
15}
16
17impl IsAscii<&str> {
18    pub const fn const_eval(&self) -> bool {
19        IsAscii(self.0.as_bytes()).const_eval()
20    }
21}
22
23impl<const N: usize> IsAscii<&[u8; N]> {
24    pub const fn const_eval(&self) -> bool {
25        IsAscii(self.0.as_slice()).const_eval()
26    }
27}
28
29/// Checks if all characters in this (string) slice are within the ASCII range.
30///
31/// The input type must be one of:
32/// + [`&str`](str)
33/// + [`&[u8]`](slice)
34/// + [`&[u8; N]`](array)
35///
36/// This macro is [const-fn compatible](./index.html#const-fn-compatible).
37///
38/// # Examples
39///
40/// ```
41/// const S1: &str = "hello!\n";
42/// const S2: &str = "你好!";
43///
44/// const _: () = {
45///     assert!(const_str::is_ascii!(S1));              // true
46///     assert!(!const_str::is_ascii!(S2));             // false
47///     assert!(!const_str::is_ascii!(b"\x80\x00"));    // false
48/// };
49/// ```
50///
51#[macro_export]
52macro_rules! is_ascii {
53    ($s:expr) => {
54        $crate::__ctfe::IsAscii($s).const_eval()
55    };
56}
57
58#[cfg(test)]
59mod tests {
60    #[test]
61    fn test_is_ascii() {
62        const S1: &str = "hello!\n";
63        const S2: &str = "你好!";
64        const S3: &str = "";
65        const S4: &str = "ASCII123";
66
67        let r1 = is_ascii!(S1);
68        let r2 = is_ascii!(S2);
69        let r3 = is_ascii!(S3);
70        let r4 = is_ascii!(S4);
71
72        assert!(r1);
73        assert!(!r2);
74        assert!(r3); // empty string is ASCII
75        assert!(r4);
76
77        // Test with byte slices
78        const B1: &[u8] = b"hello";
79        const B2: &[u8] = b"\x80\x00";
80
81        let rb1 = is_ascii!(B1);
82        let rb2 = is_ascii!(B2);
83
84        assert!(rb1);
85        assert!(!rb2);
86
87        // Test with byte arrays
88        const A1: &[u8; 5] = b"hello";
89        const A2: &[u8; 2] = b"\x80\x00";
90
91        let ra1 = is_ascii!(A1);
92        let ra2 = is_ascii!(A2);
93
94        assert!(ra1);
95        assert!(!ra2);
96    }
97}