Skip to main content

mqtt5_protocol/
numeric.rs

1pub const F64_MAX_SAFE_INTEGER: u64 = 9_007_199_254_740_991;
2
3#[must_use]
4pub fn u128_to_u64_saturating(value: u128) -> u64 {
5    if value <= u128::from(u64::MAX) {
6        #[allow(clippy::cast_possible_truncation)]
7        let result = value as u64;
8        result
9    } else {
10        u64::MAX
11    }
12}
13
14#[must_use]
15pub fn u128_to_f64_saturating(value: u128) -> f64 {
16    if value <= u128::from(F64_MAX_SAFE_INTEGER) {
17        #[allow(clippy::cast_precision_loss)]
18        let result = value as f64;
19        result
20    } else {
21        f64::MAX
22    }
23}
24
25#[must_use]
26pub fn usize_to_f64_saturating(value: usize) -> f64 {
27    u64_to_f64_saturating(value as u64)
28}
29
30#[must_use]
31pub fn u64_to_f64_saturating(value: u64) -> f64 {
32    if value <= F64_MAX_SAFE_INTEGER {
33        #[allow(clippy::cast_precision_loss)]
34        let result = value as f64;
35        result
36    } else {
37        f64::MAX
38    }
39}
40
41#[must_use]
42pub fn u128_to_u32_saturating(value: u128) -> u32 {
43    if value <= u128::from(u32::MAX) {
44        #[allow(clippy::cast_possible_truncation)]
45        let result = value as u32;
46        result
47    } else {
48        u32::MAX
49    }
50}
51
52#[must_use]
53pub fn usize_to_u32_saturating(value: usize) -> u32 {
54    u32::try_from(value).unwrap_or(u32::MAX)
55}
56
57#[must_use]
58pub fn u64_to_u32_saturating(value: u64) -> u32 {
59    u32::try_from(value).unwrap_or(u32::MAX)
60}
61
62#[must_use]
63pub fn u64_to_u16_saturating(value: u64) -> u16 {
64    u16::try_from(value).unwrap_or(u16::MAX)
65}
66
67#[must_use]
68pub fn usize_to_u16_saturating(value: usize) -> u16 {
69    u16::try_from(value).unwrap_or(u16::MAX)
70}
71
72#[must_use]
73pub fn i32_to_u32_saturating(value: i32) -> u32 {
74    if value < 0 {
75        0
76    } else {
77        #[allow(clippy::cast_sign_loss)]
78        let result = value as u32;
79        result
80    }
81}
82
83#[must_use]
84#[allow(clippy::cast_precision_loss)]
85pub fn f64_to_u64_saturating(value: f64) -> u64 {
86    const U64_MAX_AS_F64: f64 = u64::MAX as f64;
87    if value < 0.0 {
88        0
89    } else if value >= U64_MAX_AS_F64 {
90        u64::MAX
91    } else {
92        #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
93        let result = value as u64;
94        result
95    }
96}
97
98#[cfg(test)]
99mod tests {
100    use super::*;
101
102    #[test]
103    fn test_u128_to_u64_saturating() {
104        assert_eq!(u128_to_u64_saturating(0), 0);
105        assert_eq!(u128_to_u64_saturating(1000), 1000);
106        assert_eq!(u128_to_u64_saturating(u128::from(u64::MAX)), u64::MAX);
107        assert_eq!(u128_to_u64_saturating(u128::MAX), u64::MAX);
108    }
109
110    #[test]
111    fn test_u128_to_f64_saturating() {
112        assert!((u128_to_f64_saturating(0) - 0.0).abs() < f64::EPSILON);
113        assert!((u128_to_f64_saturating(1000) - 1000.0).abs() < f64::EPSILON);
114        assert!((u128_to_f64_saturating(u128::MAX) - f64::MAX).abs() < f64::EPSILON);
115    }
116
117    #[test]
118    fn test_usize_to_f64_saturating() {
119        assert!((usize_to_f64_saturating(0) - 0.0).abs() < f64::EPSILON);
120        assert!((usize_to_f64_saturating(1000) - 1000.0).abs() < f64::EPSILON);
121    }
122
123    #[test]
124    fn test_usize_to_u32_saturating() {
125        assert_eq!(usize_to_u32_saturating(0), 0);
126        assert_eq!(usize_to_u32_saturating(1000), 1000);
127        assert_eq!(usize_to_u32_saturating(u32::MAX as usize), u32::MAX);
128    }
129
130    #[test]
131    fn test_u64_to_u16_saturating() {
132        assert_eq!(u64_to_u16_saturating(0), 0);
133        assert_eq!(u64_to_u16_saturating(1000), 1000);
134        assert_eq!(u64_to_u16_saturating(u64::from(u16::MAX)), u16::MAX);
135        assert_eq!(u64_to_u16_saturating(u64::MAX), u16::MAX);
136    }
137
138    #[test]
139    fn test_i32_to_u32_saturating() {
140        assert_eq!(i32_to_u32_saturating(-100), 0);
141        assert_eq!(i32_to_u32_saturating(0), 0);
142        assert_eq!(i32_to_u32_saturating(1000), 1000);
143        #[allow(clippy::cast_sign_loss)]
144        let expected = i32::MAX as u32;
145        assert_eq!(i32_to_u32_saturating(i32::MAX), expected);
146    }
147}