use crate::*; #[derive(Copy, Clone)] pub struct Proportion { pub(crate) value: T, } impl Proportion { pub fn new(value: I) -> Self { Self { value: value.clamp() } } pub const MIN: Self = Proportion { value: ::MIN, }; pub const MAX: Self = Proportion { value: ::MAX, }; pub const ZERO: Self = Self::MIN; pub const ONE: Self = Self::MAX; pub fn set(&mut self, new_value: I) { self.value = new_value.clamp(); } pub fn is_min(&self) -> bool { self.value == I::MIN } pub fn is_max(&self) -> bool { self.value == I::MAX } pub fn is_zero(&self) -> bool { self.is_min() } pub fn is_one(&self) -> bool { self.is_max() } pub fn as_u8(&self) -> u8 { self.value.as_u8() } pub fn as_f32(&self) -> f32 { self.value.as_f32() } pub fn as_f64(&self) -> f64 { self.value.as_f64() } pub fn invert(&self) -> Self { Self { value: I::MAX - self.value, } } pub fn value(&self) -> I { self.value } } macro_rules! impl_mul { ($type:ty, $method:ident) => { impl std::ops::Mul> for $type { type Output = $type; fn mul(self, proportion: Proportion) -> $type { proportion.value.$method(self) } } impl std::ops::Mul<$type> for Proportion { type Output = $type; fn mul(self, value: $type) -> $type { self.value.$method(value) } } impl std::ops::Mul<&Proportion> for $type { type Output = $type; fn mul(self, proportion: &Proportion) -> $type { proportion.value.$method(self) } } impl std::ops::Mul<$type> for &Proportion { type Output = $type; fn mul(self, value: $type) -> $type { self.value.$method(value) } } }; } impl_mul!(u8, mul_u8); impl_mul!(u16, mul_u16); impl_mul!(u32, mul_u32); impl_mul!(f32, mul_f32); impl_mul!(f64, mul_f64); use std::fmt::{Debug, Display, Formatter}; impl Debug for Proportion { fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { write!(f, "Proportion {{ {:.2} }}", self.as_f32()) } } impl Display for Proportion { fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { write!(f, "{:.2}", self.as_f32()) } }