diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2023-12-24 21:07:11 +1300 |
---|---|---|
committer | Ben Bridle <bridle.benjamin@gmail.com> | 2023-12-24 21:07:11 +1300 |
commit | 291bb4de2a2e5940fbebd8d400f35c1fc3b0c7a2 (patch) | |
tree | 57fc89b43b72779f8192fac890a983ad94c9f6d1 /src/internal.rs | |
download | proportion-9b455098f5057bf1ec16d02c017ab5a3e860fd5a.zip |
Diffstat (limited to 'src/internal.rs')
-rw-r--r-- | src/internal.rs | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/internal.rs b/src/internal.rs new file mode 100644 index 0000000..ca099a2 --- /dev/null +++ b/src/internal.rs @@ -0,0 +1,90 @@ +pub trait Internal: Copy + Clone + PartialEq + std::ops::Sub<Output = Self> { + const MIN: Self; + const MAX: Self; + + fn clamp(self) -> Self; + fn as_u8(self) -> u8; + fn as_f32(self) -> f32; + fn as_f64(self) -> f64; + + fn mul_u8(self, value: u8) -> u8; + fn mul_u16(self, value: u16) -> u16; + fn mul_u32(self, value: u32) -> u32; + fn mul_f32(self, value: f32) -> f32; + fn mul_f64(self, value: f64) -> f64; +} + +impl Internal for u8 { + const MIN: Self = u8::MIN; + const MAX: Self = u8::MAX; + + fn clamp(self) -> Self { + self + } + fn as_u8(self) -> u8 { + self + } + fn as_f32(self) -> f32 { + self as f32 / u8::MAX as f32 + } + fn as_f64(self) -> f64 { + self as f64 / u8::MAX as f64 + } + + fn mul_u8(self, value: u8) -> u8 { + (value as u16 * self as u16 / 255u16) as u8 + } + fn mul_u16(self, value: u16) -> u16 { + (value as u32 * self as u32 / 255u32) as u16 + } + fn mul_u32(self, value: u32) -> u32 { + (value as u64 * self as u64 / 255u64) as u32 + } + fn mul_f32(self, value: f32) -> f32 { + value * self.as_f32() + } + fn mul_f64(self, value: f64) -> f64 { + value * self.as_f64() + } +} + +macro_rules! impl_for_float { + ($type:ty) => { + impl Internal for $type { + const MIN: Self = 0.0; + const MAX: Self = 1.0; + + fn clamp(self) -> Self { + <$type>::clamp(self, <Self as Internal>::MIN, <Self as Internal>::MAX) + } + fn as_u8(self) -> u8 { + (self * 255.0) as u8 + } + fn as_f32(self) -> f32 { + self as f32 + } + fn as_f64(self) -> f64 { + self as f64 + } + + fn mul_u8(self, value: u8) -> u8 { + (value as Self * self) as u8 + } + fn mul_u16(self, value: u16) -> u16 { + (value as Self * self).round() as u16 + } + fn mul_u32(self, value: u32) -> u32 { + (value as Self * self).round() as u32 + } + fn mul_f32(self, value: f32) -> f32 { + value * self.as_f32() + } + fn mul_f64(self, value: f64) -> f64 { + value * self.as_f64() + } + } + }; +} + +impl_for_float!(f32); +impl_for_float!(f64); |