use std::convert::TryFrom;
#[inline]
pub fn u64_to_usize(value: u64) -> Result<usize, String> {
usize::try_from(value).map_err(|_| {
format!(
"File offset {value} exceeds maximum addressable size on this platform"
)
})
}
#[inline]
pub fn u32_to_u16(value: u32) -> Result<u16, String> {
u16::try_from(value).map_err(|_| format!("Value {value} exceeds u16 maximum (65535)"))
}
#[inline]
pub fn usize_to_u32(value: usize) -> Result<u32, String> {
u32::try_from(value).map_err(|_| format!("Value {value} exceeds u32 maximum"))
}
#[inline]
pub fn u32_to_i32(value: u32) -> Result<i32, String> {
i32::try_from(value).map_err(|_| format!("Value {value} exceeds i32 maximum"))
}
#[inline]
#[must_use]
pub fn f64_to_pixel_index(value: f64, max_value: usize) -> Option<usize> {
if value.is_nan() || value < 0.0 {
return None;
}
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
let index = value as usize;
if index >= max_value {
None
} else {
Some(index)
}
}
#[inline]
#[must_use]
pub fn f64_to_clamped_pixel(value: f64, max_value: usize) -> usize {
if value.is_nan() || value < 0.0 {
return 0;
}
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
let index = value as usize;
if index >= max_value {
max_value.saturating_sub(1)
} else {
index
}
}
#[inline]
#[must_use]
pub fn isize_to_usize(value: isize) -> Option<usize> {
if value < 0 {
None
} else {
#[allow(clippy::cast_sign_loss)]
Some(value as usize)
}
}
#[inline]
#[must_use]
pub fn isize_to_clamped_usize(value: isize, max_value: usize) -> usize {
if value < 0 {
0
} else {
#[allow(clippy::cast_sign_loss)]
let u = value as usize;
if u >= max_value {
max_value.saturating_sub(1)
} else {
u
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_u64_to_usize() {
assert!(u64_to_usize(0).is_ok());
assert!(u64_to_usize(1000).is_ok());
#[cfg(target_pointer_width = "64")]
assert!(u64_to_usize(u64::MAX).is_ok());
}
#[test]
fn test_u32_to_u16() {
assert_eq!(u32_to_u16(0), Ok(0));
assert_eq!(u32_to_u16(65535), Ok(65535));
assert!(u32_to_u16(65536).is_err());
}
#[test]
fn test_f64_to_pixel_index() {
assert_eq!(f64_to_pixel_index(0.0, 100), Some(0));
assert_eq!(f64_to_pixel_index(50.5, 100), Some(50));
assert_eq!(f64_to_pixel_index(99.9, 100), Some(99));
assert_eq!(f64_to_pixel_index(100.0, 100), None);
assert_eq!(f64_to_pixel_index(-1.0, 100), None);
assert_eq!(f64_to_pixel_index(f64::NAN, 100), None);
}
#[test]
fn test_f64_to_clamped_pixel() {
assert_eq!(f64_to_clamped_pixel(0.0, 100), 0);
assert_eq!(f64_to_clamped_pixel(50.5, 100), 50);
assert_eq!(f64_to_clamped_pixel(150.0, 100), 99);
assert_eq!(f64_to_clamped_pixel(-10.0, 100), 0);
assert_eq!(f64_to_clamped_pixel(f64::NAN, 100), 0);
}
#[test]
fn test_isize_to_usize() {
assert_eq!(isize_to_usize(0), Some(0));
assert_eq!(isize_to_usize(100), Some(100));
assert_eq!(isize_to_usize(-1), None);
}
#[test]
fn test_isize_to_clamped_usize() {
assert_eq!(isize_to_clamped_usize(50, 100), 50);
assert_eq!(isize_to_clamped_usize(-10, 100), 0);
assert_eq!(isize_to_clamped_usize(150, 100), 99);
}
}