• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

chrjabs / rustsat / 21956286629

12 Feb 2026 05:01PM UTC coverage: 61.964% (+1.1%) from 60.815%
21956286629

Pull #598

github

web-flow
Merge 9cd381b5b into 0a46d8409
Pull Request #598: Major parser rewrite

1550 of 1784 new or added lines in 20 files covered. (86.88%)

29 existing lines in 9 files now uncovered.

14178 of 22881 relevant lines covered (61.96%)

140791.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.59
/src/utils.rs
1
//! # Library-Internal Utilities
2

3
/// Computes the number of digits needed to represent a number in a given base
4
///
5
/// # Panics
6
///
7
/// If `basis` is `1` and `number` is larger than `u32`.
8
#[cfg_attr(feature = "_internals", visibility::make(pub))]
868✔
9
#[cfg_attr(docsrs, doc(cfg(feature = "_internals")))]
868✔
10
#[must_use]
868✔
11
pub(crate) fn digits(mut number: usize, mut basis: u8) -> u32 {
868✔
12
    debug_assert_ne!(basis, 0);
868✔
13
    if number == 0 {
868✔
14
        return 1;
6✔
15
    }
862✔
16
    if basis == 1 {
862✔
17
        return u32::try_from(std::cmp::max(number, 1))
×
18
            .expect("number of digits does not fit in u32");
×
19
    }
862✔
20
    let mut digits = 0;
862✔
21
    if basis.is_power_of_two() {
862✔
22
        // optimized version using shift operations
23
        let mut pow: u8 = 0;
860✔
24
        basis >>= 1;
860✔
25
        while basis > 0 {
1,726✔
26
            pow += 1;
866✔
27
            basis >>= 1;
866✔
28
        }
866✔
29
        while number > 0 {
2,982✔
30
            digits += 1;
2,122✔
31
            number >>= pow;
2,122✔
32
        }
2,122✔
33
    } else {
34
        while number > 0 {
9✔
35
            digits += 1;
7✔
36
            number /= basis as usize;
7✔
37
        }
7✔
38
    }
39
    digits
862✔
40
}
868✔
41

42
/// Helper function to create a slice from a pointer and size
43
/// with special case when `cnt` is 0 (in which case `ptr` may be null)
44
///
45
/// # Safety
46
///
47
/// Same requirements as for [`std::slice::from_raw_parts`], with the exception that `ptr` is allowed to be null if `cnt == 0`.
48
pub unsafe fn from_raw_parts_maybe_null<'a, T>(ptr: *const T, cnt: usize) -> &'a [T] {
4,406✔
49
    if cnt == 0 {
4,406✔
50
        &[]
5✔
51
    } else {
52
        std::slice::from_raw_parts(ptr, cnt)
4,401✔
53
    }
54
}
4,406✔
55

56
/// Computes the starting offset of `sub` in `parent`
57
///
58
/// Returns [`None`] if `sub` is not part of `parent`
59
#[must_use]
60
pub fn substr_offset(parent: &str, sub: &str) -> Option<usize> {
282✔
61
    let parent_beg = parent.as_ptr() as usize;
282✔
62
    let sub_beg = sub.as_ptr() as usize;
282✔
63
    if sub_beg < parent_beg || sub_beg > parent_beg.wrapping_add(parent.len()) {
282✔
NEW
64
        None
×
65
    } else {
66
        Some(sub_beg.wrapping_sub(parent_beg))
282✔
67
    }
68
}
282✔
69

70
/// A wrapper around an iterator to only yield a limited number of elements and then stop
71
///
72
/// As opposed to [`std::iter::Take`] this does not take ownership of the original iterator
73
#[derive(Debug)]
74
pub struct LimitedIter<'iter, I> {
75
    iter: &'iter mut I,
76
    remaining: usize,
77
}
78

79
impl<'iter, I> LimitedIter<'iter, I> {
80
    /// Creates a new iterator that yields at most `remaining` elements
81
    pub fn new(iter: &'iter mut I, remaining: usize) -> Self {
64✔
82
        Self { iter, remaining }
64✔
83
    }
64✔
84
}
85

86
impl<I> Iterator for LimitedIter<'_, I>
87
where
88
    I: Iterator,
89
{
90
    type Item = <I as Iterator>::Item;
91

92
    fn next(&mut self) -> Option<Self::Item> {
215✔
93
        if self.remaining == 0 {
215✔
94
            return None;
33✔
95
        }
182✔
96
        self.remaining -= 1;
182✔
97
        self.iter.next()
182✔
98
    }
215✔
99
}
100

101
macro_rules! unreachable_none {
102
    ($opt:expr) => {{
103
        if let Some(val) = $opt {
104
            val
105
        } else {
106
            unreachable!()
107
        }
108
    }};
109
}
110
pub(crate) use unreachable_none;
111

112
macro_rules! unreachable_err {
113
    ($res:expr) => {{
114
        if let Ok(val) = $res {
115
            val
116
        } else {
117
            unreachable!()
118
        }
119
    }};
120
}
121
pub(crate) use unreachable_err;
122

123
pub use timer::Timer;
124

125
#[cfg(any(target_family = "unix", target_family = "windows"))]
126
mod timer {
127
    /// A timer to measure execution time.
128
    ///
129
    /// On `unix`/`windows` systems, this is based on `cpu_time::ThreadTime`, on `wasm` systems, it
130
    /// is based on `web-time`
131
    #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
132
    pub struct Timer(cpu_time::ThreadTime);
133

134
    impl Timer {
135
        /// Gets the current time
136
        #[must_use]
137
        pub fn now() -> Self {
24,087✔
138
            Timer(cpu_time::ThreadTime::now())
24,087✔
139
        }
24,087✔
140

141
        /// Gets the amount of time elapsed since the timer was initialized
142
        #[must_use]
143
        pub fn elapsed(&self) -> std::time::Duration {
24,087✔
144
            self.0.elapsed()
24,087✔
145
        }
24,087✔
146
    }
147
}
148

149
#[cfg(not(any(target_family = "unix", target_family = "windows")))]
150
mod timer {
151
    /// A timer to measure execution time.
152
    ///
153
    /// On `unix`/`windows` systems, this is based on `cpu_time::ThreadTime`, on `wasm` systems, it
154
    /// is based on `web-time`
155
    #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
156
    pub struct Timer(web_time::Instant);
157

158
    impl Timer {
159
        /// Gets the current time
160
        #[must_use]
161
        pub fn now() -> Self {
162
            Timer(web_time::Instant::now())
163
        }
164

165
        /// Gets the amount of time elapsed since the timer was initialized
166
        #[must_use]
167
        pub fn elapsed(&self) -> std::time::Duration {
168
            self.0.elapsed()
169
        }
170
    }
171
}
172

173
#[cfg(test)]
174
mod tests {
175
    #[test]
176
    fn digits_pow_2() {
1✔
177
        assert_eq!(super::digits(0b1111_1101, 2), 8);
1✔
178
        assert_eq!(super::digits(0b1111_1101, 4), 4);
1✔
179
        assert_eq!(super::digits(0b1111_1101, 8), 3);
1✔
180
        assert_eq!(super::digits(0b1111_1101, 16), 2);
1✔
181
    }
1✔
182

183
    #[test]
184
    fn digits_base_10() {
1✔
185
        assert_eq!(super::digits(3158, 10), 4);
1✔
186
        assert_eq!(super::digits(123, 10), 3);
1✔
187
    }
1✔
188
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc