use super::Num;
use std::mem::size_of;
pub trait FromClamped<N: Num> {
fn from_clamped(n: N) -> Self;
}
impl FromClamped<i16> for i8 {
fn from_clamped(n: i16) -> Self {
n.max(<i16>::from(<i8>::min_value()))
.min(<i16>::from(<i8>::max_value())) as Self
}
}
impl FromClamped<i32> for i8 {
fn from_clamped(n: i32) -> Self {
n.max(<i32>::from(<i8>::min_value()))
.min(<i32>::from(<i8>::max_value())) as Self
}
}
impl FromClamped<i64> for i8 {
fn from_clamped(n: i64) -> Self {
n.max(<i64>::from(<i8>::min_value()))
.min(<i64>::from(<i8>::max_value())) as Self
}
}
impl FromClamped<u8> for i8 {
fn from_clamped(n: u8) -> Self {
n.min(<i8>::max_value() as u8) as Self
}
}
impl FromClamped<u16> for i8 {
fn from_clamped(n: u16) -> Self {
n.min(<i8>::max_value() as u16) as Self
}
}
impl FromClamped<u32> for i8 {
fn from_clamped(n: u32) -> Self {
n.min(<i8>::max_value() as u32) as Self
}
}
impl FromClamped<u64> for i8 {
fn from_clamped(n: u64) -> Self {
n.min(<i8>::max_value() as u64) as Self
}
}
impl FromClamped<f32> for i8 {
fn from_clamped(n: f32) -> Self {
n.max(<f32>::from(<Self>::min_value()))
.min(<f32>::from(<Self>::max_value())) as Self
}
}
impl FromClamped<f64> for i8 {
fn from_clamped(n: f64) -> Self {
n.max(<f64>::from(<Self>::min_value()))
.min(<f64>::from(<Self>::max_value())) as Self
}
}
impl FromClamped<i8> for u8 {
fn from_clamped(n: i8) -> Self {
n.max(0) as Self
}
}
impl FromClamped<i16> for u8 {
fn from_clamped(n: i16) -> Self {
n.max(0).min(<i16>::from(<u8>::max_value())) as Self
}
}
impl FromClamped<i32> for u8 {
fn from_clamped(n: i32) -> Self {
n.max(0).min(<i32>::from(<u8>::max_value())) as Self
}
}
impl FromClamped<i64> for u8 {
fn from_clamped(n: i64) -> Self {
n.max(0).min(<i64>::from(<u8>::max_value())) as Self
}
}
impl FromClamped<u16> for u8 {
fn from_clamped(n: u16) -> Self {
n.min(<u16>::from(<u8>::max_value())) as Self
}
}
impl FromClamped<u32> for u8 {
fn from_clamped(n: u32) -> Self {
n.min(<u32>::from(<u8>::max_value())) as Self
}
}
impl FromClamped<u64> for u8 {
fn from_clamped(n: u64) -> Self {
n.min(<u64>::from(<u8>::max_value())) as Self
}
}
impl FromClamped<f32> for u8 {
fn from_clamped(n: f32) -> Self {
n.max(0.0).min(<f32>::from(<Self>::max_value())) as Self
}
}
impl FromClamped<f64> for u8 {
fn from_clamped(n: f64) -> Self {
n.max(0.0).min(<f64>::from(<u8>::max_value())) as Self
}
}
impl FromClamped<i32> for i16 {
fn from_clamped(n: i32) -> Self {
n.max(<i32>::from(<Self>::min_value()))
.min(<i32>::from(<Self>::max_value())) as Self
}
}
impl FromClamped<i64> for i16 {
fn from_clamped(n: i64) -> Self {
n.max(<i64>::from(<Self>::min_value()))
.min(<i64>::from(<Self>::max_value())) as Self
}
}
impl FromClamped<u16> for i16 {
fn from_clamped(n: u16) -> Self {
n.min(<i16>::max_value() as u16) as Self
}
}
impl FromClamped<u32> for i16 {
fn from_clamped(n: u32) -> Self {
n.min(<i16>::max_value() as u32) as Self
}
}
impl FromClamped<u64> for i16 {
fn from_clamped(n: u64) -> Self {
n.min(<i16>::max_value() as u64) as Self
}
}
impl FromClamped<f32> for i16 {
fn from_clamped(n: f32) -> Self {
n.max(<f32>::from(<Self>::min_value()))
.min(<f32>::from(<Self>::max_value())) as Self
}
}
impl FromClamped<f64> for i16 {
fn from_clamped(n: f64) -> Self {
n.max(<f64>::from(<Self>::min_value()))
.min(<f64>::from(<Self>::max_value())) as Self
}
}
impl FromClamped<i16> for u16 {
fn from_clamped(n: i16) -> Self {
n.max(0) as Self
}
}
impl FromClamped<i32> for u16 {
fn from_clamped(n: i32) -> Self {
n.max(0).min(<i32>::from(<u16>::max_value())) as Self
}
}
impl FromClamped<i64> for u16 {
fn from_clamped(n: i64) -> Self {
n.max(0).min(<i64>::from(<u16>::max_value())) as Self
}
}
impl FromClamped<u32> for u16 {
fn from_clamped(n: u32) -> Self {
n.min(<u32>::from(<u16>::max_value())) as Self
}
}
impl FromClamped<u64> for u16 {
fn from_clamped(n: u64) -> Self {
n.min(<u64>::from(<u16>::max_value())) as Self
}
}
impl FromClamped<f32> for u16 {
fn from_clamped(n: f32) -> Self {
n.max(0.0).min(<f32>::from(<u16>::max_value())) as Self
}
}
impl FromClamped<f64> for u16 {
fn from_clamped(n: f64) -> Self {
n.max(0.0).min(<f64>::from(<u16>::max_value())) as Self
}
}
impl FromClamped<i64> for i32 {
fn from_clamped(n: i64) -> Self {
n.max(<i64>::from(<i32>::min_value()))
.min(<i64>::from(<i32>::max_value())) as Self
}
}
impl FromClamped<u32> for i32 {
fn from_clamped(n: u32) -> Self {
n.min(<i32>::max_value() as u32) as Self
}
}
impl FromClamped<u64> for i32 {
fn from_clamped(n: u64) -> Self {
n.min(<i32>::max_value() as u64) as Self
}
}
impl FromClamped<f32> for i32 {
fn from_clamped(n: f32) -> Self {
n.max(<Self>::min_value() as f32)
.min(<Self>::max_value() as f32) as Self
}
}
impl FromClamped<f64> for i32 {
fn from_clamped(n: f64) -> Self {
n.max(<Self>::min_value() as f64)
.min(<Self>::max_value() as f64) as Self
}
}
impl FromClamped<i32> for u32 {
fn from_clamped(n: i32) -> Self {
n.max(0) as Self
}
}
impl FromClamped<i64> for u32 {
fn from_clamped(n: i64) -> Self {
n.max(0).min(<i64>::from(<u32>::max_value())) as Self
}
}
impl FromClamped<u64> for u32 {
fn from_clamped(n: u64) -> Self {
n.min(<u64>::from(<u32>::max_value())) as Self
}
}
impl FromClamped<f32> for u32 {
fn from_clamped(n: f32) -> Self {
n.max(0.0).min(<u32>::max_value() as f32) as Self
}
}
impl FromClamped<f64> for u32 {
fn from_clamped(n: f64) -> Self {
n.max(0.0).min(<f64>::from(<u32>::max_value())) as Self
}
}
impl FromClamped<u64> for i64 {
fn from_clamped(n: u64) -> Self {
n.min(<i64>::max_value() as u64) as Self
}
}
impl FromClamped<f32> for i64 {
fn from_clamped(n: f32) -> Self {
n.max(<Self>::min_value() as f32)
.min(<Self>::max_value() as f32) as Self
}
}
impl FromClamped<f64> for i64 {
fn from_clamped(n: f64) -> Self {
n.max(<Self>::min_value() as f64)
.min(<Self>::max_value() as f64) as Self
}
}
impl FromClamped<i64> for u64 {
fn from_clamped(n: i64) -> Self {
n.max(0) as Self
}
}
impl FromClamped<f32> for u64 {
fn from_clamped(n: f32) -> Self {
n.max(0.0).min(<u64>::max_value() as f32) as Self
}
}
impl FromClamped<f64> for u64 {
fn from_clamped(n: f64) -> Self {
n.max(0.0).min(<u64>::max_value() as f64) as Self
}
}
impl FromClamped<i8> for usize {
fn from_clamped(n: i8) -> Self {
n.max(0) as Self
}
}
impl FromClamped<i16> for usize {
fn from_clamped(n: i16) -> Self {
if size_of::<u16>() <= size_of::<usize>() {
n.max(0) as Self
} else {
n.max(0).min(<usize>::max_value() as i16) as Self
}
}
}
impl FromClamped<i32> for usize {
fn from_clamped(n: i32) -> Self {
if size_of::<u16>() <= size_of::<usize>() {
n.max(0) as Self
} else {
n.max(0).min(<usize>::max_value() as i32) as Self
}
}
}
impl FromClamped<i64> for usize {
fn from_clamped(n: i64) -> Self {
if size_of::<u16>() <= size_of::<usize>() {
n.max(0) as Self
} else {
n.max(0).min(<usize>::max_value() as i64) as Self
}
}
}
impl FromClamped<u16> for usize {
fn from_clamped(n: u16) -> Self {
if size_of::<u16>() <= size_of::<usize>() {
n as Self
} else {
n.min(<usize>::max_value() as u16) as Self
}
}
}
impl FromClamped<u32> for usize {
fn from_clamped(n: u32) -> Self {
if size_of::<u32>() <= size_of::<usize>() {
n as Self
} else {
n.min(<usize>::max_value() as u32) as Self
}
}
}
impl FromClamped<u64> for usize {
fn from_clamped(n: u64) -> Self {
if size_of::<u64>() <= size_of::<usize>() {
n as Self
} else {
n.min(<usize>::max_value() as u64) as Self
}
}
}
impl FromClamped<f32> for usize {
fn from_clamped(n: f32) -> Self {
n.max(0.0).min(<usize>::max_value() as f32) as Self
}
}
impl FromClamped<f64> for usize {
fn from_clamped(n: f64) -> Self {
n.max(0.0).min(<usize>::max_value() as f64) as Self
}
}
impl FromClamped<i16> for f32 {
fn from_clamped(n: i16) -> Self {
<f32>::from(n)
}
}
impl FromClamped<i32> for f32 {
fn from_clamped(n: i32) -> Self {
n as f32
}
}
impl FromClamped<i64> for f32 {
fn from_clamped(n: i64) -> Self {
n as f32
}
}
impl FromClamped<u32> for f32 {
fn from_clamped(n: u32) -> Self {
n as f32
}
}
impl FromClamped<u64> for f32 {
fn from_clamped(n: u64) -> Self {
n as f32
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn u8_to_i8() {
assert_eq!(<i8>::from_clamped(<u8>::max_value()), <i8>::max_value());
}
#[test]
fn i8_to_u8() {
assert_eq!(<u8>::from_clamped(<i8>::min_value()), 0);
assert_eq!(
<u8>::from_clamped(<i8>::max_value()),
<i8>::max_value() as u8
);
}
}