1pub fn round_up<T: Into<U>, U: Copy + num_traits::PrimInt>(offset: U, block_size: T) -> Option<U> {
11 let block_size = block_size.into();
12 #[allow(clippy::eq_op)]
13 let one = block_size / block_size;
14 Some(round_down(offset.checked_add(&(block_size - one))?, block_size))
15}
16
17pub fn round_down<
19 T: Into<U>,
20 U: Copy + std::ops::Rem<U, Output = U> + std::ops::Sub<U, Output = U>,
21>(
22 offset: U,
23 block_size: T,
24) -> U {
25 let block_size = block_size.into();
26 offset - offset % block_size
27}
28
29pub fn round_div(numerator: u64, denominator: u64) -> Option<u64> {
33 numerator.checked_add(denominator / 2)?.checked_div(denominator)
34}
35
36#[cfg(test)]
37mod tests {
38 use crate::round::round_div;
39
40 #[test]
41 fn test_round_div() {
42 assert_eq!(round_div(9, 4), Some(2));
43 assert_eq!(round_div(10, 4), Some(3));
44 assert_eq!(round_div(11, 4), Some(3));
45 assert_eq!(round_div(12, 4), Some(3));
46 assert_eq!(round_div(13, 4), Some(3));
47 assert_eq!(round_div(14, 4), Some(4));
48 assert_eq!(round_div(0, 1), Some(0));
49 assert_eq!(round_div(100, 0), None);
50 assert_eq!(round_div(u64::MAX, 2), None);
51 }
52}