1use std::cmp;
17use num_traits::Float;
18
19pub fn clamp<T: Ord> (value: T, (min, max): (T, T)) -> T {
21 cmp::min(cmp::max(value, min), max)
22}
23
24pub fn clamp_float<F: Float>(value: F, (min, max): (F, F)) -> F {
26 F::min(F::max(value, min), max)
27}
28
29pub fn pretty_print(mut i: u64) -> String {
31 let mut result: String = String::new();
32 let separator = '_';
33
34 let mut chunks = vec![i % 1000];
36 i /= 1000;
37
38 while i != 0 {
39 chunks.push(i % 1000);
40 i /= 1000;
41 }
42
43 for (ix, n) in chunks.iter().rev().enumerate() {
44 let digits = if ix == 0 { n.to_string() } else { format!("{:03}", n) };
45 result.push_str(&digits);
46
47 if ix + 1 != chunks.len() {
48 result.push(separator);
49 }
50 }
51
52 result
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn check_pretty_print() {
61 assert_eq!(&pretty_print(0), "0");
62 assert_eq!(&pretty_print(512), "512");
63 assert_eq!(&pretty_print(1024), "1_024");
64 assert_eq!(&pretty_print(16777216), "16_777_216");
65 }
66
67 #[test]
68 fn check_clamp() {
69 let range = (0, 255);
70 assert_eq!(clamp( -1, range), 0);
71 assert_eq!(clamp(100, range), 100);
72 assert_eq!(clamp(256, range), 255);
73
74 let range = (0.0, 1.0);
75 assert_eq!(clamp_float(-1.0, range), 0.0);
76 assert_eq!(clamp_float( 0.5, range), 0.5);
77 assert_eq!(clamp_float( 2.0, range), 1.0);
78 }
79}