Coverage Report

Created: 2025-06-16 06:50

/rust/registry/src/index.crates.io-6f17d22bba15001f/zerotrie-0.1.3/src/helpers.rs
Line
Count
Source (jump to first uncovered line)
1
// This file is part of ICU4X. For terms of use, please see the file
2
// called LICENSE at the top level of the ICU4X source tree
3
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5
pub(crate) trait MaybeSplitAt<T> {
6
    /// Like slice::split_at but returns an Option instead of panicking
7
    /// if the index is out of range.
8
    fn maybe_split_at(&self, mid: usize) -> Option<(&Self, &Self)>;
9
    /// Like slice::split_at but debug-panics and returns an empty second slice
10
    /// if the index is out of range.
11
    fn debug_split_at(&self, mid: usize) -> (&Self, &Self);
12
}
13
14
impl<T> MaybeSplitAt<T> for [T] {
15
    #[inline]
16
0
    fn maybe_split_at(&self, mid: usize) -> Option<(&Self, &Self)> {
17
0
        if mid > self.len() {
18
0
            None
19
        } else {
20
            // Note: We're trusting the compiler to inline this and remove the assertion
21
            // hiding on the top of slice::split_at: `assert(mid <= self.len())`
22
0
            Some(self.split_at(mid))
23
        }
24
0
    }
Unexecuted instantiation: <[u8] as zerotrie::helpers::MaybeSplitAt<u8>>::maybe_split_at
Unexecuted instantiation: <[_] as zerotrie::helpers::MaybeSplitAt<_>>::maybe_split_at
25
    #[inline]
26
0
    fn debug_split_at(&self, mid: usize) -> (&Self, &Self) {
27
0
        if mid > self.len() {
28
0
            debug_assert!(false, "debug_split_at: index expected to be in range");
29
0
            (self, &[])
30
        } else {
31
            // Note: We're trusting the compiler to inline this and remove the assertion
32
            // hiding on the top of slice::split_at: `assert(mid <= self.len())`
33
0
            self.split_at(mid)
34
        }
35
0
    }
36
}
37
38
pub(crate) trait DebugUnwrapOr<T> {
39
    /// Unwraps the option or panics in debug mode, returning the `gigo_value`
40
    fn debug_unwrap_or(self, gigo_value: T) -> T;
41
}
42
43
impl<T> DebugUnwrapOr<T> for Option<T> {
44
    #[inline]
45
0
    fn debug_unwrap_or(self, gigo_value: T) -> T {
46
0
        match self {
47
0
            Some(x) => x,
48
            None => {
49
0
                debug_assert!(false, "debug_unwrap_or called on a None value");
50
0
                gigo_value
51
            }
52
        }
53
0
    }
Unexecuted instantiation: <core::option::Option<&[u8]> as zerotrie::helpers::DebugUnwrapOr<&[u8]>>::debug_unwrap_or
Unexecuted instantiation: <core::option::Option<&u8> as zerotrie::helpers::DebugUnwrapOr<&u8>>::debug_unwrap_or
54
}
55
56
macro_rules! debug_unwrap {
57
    ($expr:expr, return $retval:expr, $($arg:tt)+) => {
58
        match $expr {
59
            Some(x) => x,
60
            None => {
61
                debug_assert!(false, $($arg)*);
62
                return $retval;
63
            }
64
        }
65
    };
66
    ($expr:expr, return $retval:expr) => {
67
        debug_unwrap!($expr, return $retval, "invalid trie")
68
    };
69
    ($expr:expr, break, $($arg:tt)+) => {
70
        match $expr {
71
            Some(x) => x,
72
            None => {
73
                debug_assert!(false, $($arg)*);
74
                break;
75
            }
76
        }
77
    };
78
    ($expr:expr, break) => {
79
        debug_unwrap!($expr, break, "invalid trie")
80
    };
81
    ($expr:expr, $($arg:tt)+) => {
82
        debug_unwrap!($expr, return (), $($arg)*)
83
    };
84
    ($expr:expr) => {
85
        debug_unwrap!($expr, return ())
86
    };
87
}
88
89
pub(crate) use debug_unwrap;
90
91
/// The maximum number of base-10 digits required for rendering a usize.
92
/// Note: 24/10 is an approximation of 8*log10(2)
93
pub(crate) const MAX_USIZE_LEN_AS_DIGITS: usize = core::mem::size_of::<usize>() * 24 / 10 + 1;
94
95
/// Formats a usize as a string of length N, padded with spaces,
96
/// with the given prefix.
97
///
98
/// If the string is too short, the function may panic. To prevent
99
/// this, N should be MAX_USIZE_LEN_AS_DIGITS larger than M.
100
0
pub(crate) const fn const_fmt_int<const M: usize, const N: usize>(
101
0
    prefix: [u8; M],
102
0
    value: usize,
103
0
) -> [u8; N] {
104
0
    let mut output = [b' '; N];
105
0
    let mut i = 0;
106
0
    while i < M {
107
0
        output[i] = prefix[i];
108
0
        i += 1;
109
0
    }
110
0
    let mut int_only = [b' '; MAX_USIZE_LEN_AS_DIGITS];
111
0
    let mut value = value;
112
0
    let mut i = MAX_USIZE_LEN_AS_DIGITS - 1;
113
    loop {
114
0
        let x = (value % 10) as u8;
115
0
        int_only[i] = x + b'0';
116
0
        value /= 10;
117
0
        if value == 0 {
118
0
            break;
119
0
        }
120
0
        i -= 1;
121
    }
122
0
    let mut j = M;
123
0
    while i < MAX_USIZE_LEN_AS_DIGITS {
124
0
        output[j] = int_only[i];
125
0
        j += 1;
126
0
        i += 1;
127
0
    }
128
0
    output
129
0
}
130
131
#[test]
132
fn test_const_fmt_int() {
133
    assert_eq!(*b"123", const_fmt_int::<0, 3>(*b"", 123));
134
    assert_eq!(*b"123   ", const_fmt_int::<0, 6>(*b"", 123));
135
    assert_eq!(*b"abc123", const_fmt_int::<3, 6>(*b"abc", 123));
136
}