Skip to main content

parley/utils/
cast.rs

1//! Bounded numeric conversions used by rendering and timestamp helpers.
2
3#[must_use]
4pub fn u128_to_u64_saturating(value: u128) -> u64 {
5    u64::try_from(value).unwrap_or(u64::MAX)
6}
7
8#[must_use]
9pub fn usize_to_u16_saturating(value: usize) -> u16 {
10    u16::try_from(value).unwrap_or(u16::MAX)
11}
12
13#[must_use]
14pub fn usize_to_u32_saturating(value: usize) -> u32 {
15    u32::try_from(value).unwrap_or(u32::MAX)
16}
17
18#[must_use]
19pub fn usize_to_isize_saturating(value: usize) -> isize {
20    isize::try_from(value).unwrap_or(isize::MAX)
21}
22
23#[must_use]
24pub fn usize_to_i16_saturating(value: usize) -> i16 {
25    i16::try_from(value).unwrap_or(i16::MAX)
26}
27
28#[must_use]
29pub fn u16_to_i16_saturating(value: u16) -> i16 {
30    i16::try_from(value).unwrap_or(i16::MAX)
31}
32
33#[must_use]
34pub fn i16_to_u16_saturating(value: i16) -> u16 {
35    u16::try_from(value).unwrap_or(0)
36}
37
38#[must_use]
39pub fn i32_to_u16_saturating(value: i32) -> u16 {
40    if value < 0 {
41        0
42    } else {
43        u16::try_from(value).unwrap_or(u16::MAX)
44    }
45}
46
47#[must_use]
48pub fn offset_index(current: usize, len: usize, delta: isize) -> usize {
49    let max = len.saturating_sub(1);
50    if delta.is_negative() {
51        current.saturating_sub(delta.unsigned_abs())
52    } else {
53        current.saturating_add(delta.unsigned_abs()).min(max)
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn integer_conversions_saturate_at_target_bounds() {
63        assert_eq!(usize_to_u16_saturating(usize::MAX), u16::MAX);
64        assert_eq!(usize_to_u32_saturating(usize::MAX), u32::MAX);
65        assert_eq!(u128_to_u64_saturating(u128::MAX), u64::MAX);
66    }
67
68    #[test]
69    fn offset_index_clamps_to_collection_bounds() {
70        assert_eq!(offset_index(2, 5, -10), 0);
71        assert_eq!(offset_index(2, 5, 10), 4);
72        assert_eq!(offset_index(2, 5, 1), 3);
73    }
74}