math_util/
round.rs

1// Copyright (C) 2020 Daniel Mueller <deso@posteo.net>
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4use std::ops::Add;
5use std::ops::Rem;
6use std::ops::Sub;
7
8
9/// Round `value` to the next multiple of `round_to`, unless it already
10/// is a multiple.
11pub fn round_up<T>(
12  value: T,
13  round_to: T,
14) -> <T as Add<<<T as Sub<<T as Rem>::Output>>::Output as Rem<T>>::Output>>::Output
15where
16  T: Copy,
17  T: Rem<T>,
18  T: Sub<<T as Rem>::Output>,
19  T: Add<<<T as Sub<<T as Rem>::Output>>::Output as Rem<T>>::Output>,
20  <T as Sub<<T as Rem>::Output>>::Output: Rem<T>,
21{
22  value + ((round_to - (value % round_to)) % round_to)
23}
24
25
26#[cfg(test)]
27pub mod tests {
28  use super::*;
29
30
31  #[test]
32  fn rounding() {
33    assert_eq!(round_up(1, 10), 10);
34    assert_eq!(round_up(10, 100), 100);
35    assert_eq!(round_up(99, 100), 100);
36    assert_eq!(round_up(100, 100), 100);
37    assert_eq!(round_up(5, 1000), 1000);
38    assert_eq!(round_up(1, 1000), 1000);
39    assert_eq!(round_up(0, 1000), 0);
40  }
41}