First commit
This commit is contained in:
commit
57e084f53a
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "proportion"
|
||||
version = "1.0.0"
|
||||
authors = ["Ben Bridle <bridle.benjamin@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,9 @@
|
|||
use crate::Proportion;
|
||||
|
||||
impl Proportion {
|
||||
pub const MIN: Self = Proportion { value: 0.0 };
|
||||
pub const MAX: Self = Proportion { value: 1.0 };
|
||||
|
||||
pub const ZERO: Self = Self::MIN;
|
||||
pub const ONE: Self = Self::MAX;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
use crate::Proportion;
|
||||
|
||||
impl From<f64> for Proportion {
|
||||
fn from(value: f64) -> Self {
|
||||
Self::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f32> for Proportion {
|
||||
fn from(value: f32) -> Self {
|
||||
Self::new(value)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
mod constants;
|
||||
mod conversions;
|
||||
mod operator_overloads;
|
||||
mod proportion;
|
||||
|
||||
pub use proportion::Proportion;
|
|
@ -0,0 +1,27 @@
|
|||
use crate::Proportion;
|
||||
|
||||
impl std::ops::Neg for Proportion {
|
||||
type Output = Self;
|
||||
|
||||
fn neg(mut self) -> Self::Output {
|
||||
self.value = 1.0 - self.value;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Mul<f64> for Proportion {
|
||||
type Output = f64;
|
||||
|
||||
fn mul(self, rhs: f64) -> f64 {
|
||||
self.value * rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Mul<Proportion> for usize {
|
||||
type Output = usize;
|
||||
|
||||
fn mul(self, rhs: Proportion) -> usize {
|
||||
let lhs = self as f64;
|
||||
(lhs * rhs.value).round() as usize
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Proportion {
|
||||
pub(crate) value: f64,
|
||||
}
|
||||
|
||||
impl Proportion {
|
||||
pub fn new<T: Into<f64>>(value: T) -> Self {
|
||||
let mut new = Self {
|
||||
value: value.into(),
|
||||
};
|
||||
new.clamp_to_bounds();
|
||||
new
|
||||
}
|
||||
|
||||
pub fn from_fraction<T: Into<f64>>(numerator: T, denominator: T) -> Self {
|
||||
let denominator = denominator.into();
|
||||
if denominator == 0.0 {
|
||||
return Self::MAX;
|
||||
}
|
||||
let numerator = numerator.into();
|
||||
Self::new(numerator / denominator)
|
||||
}
|
||||
|
||||
pub fn value(&self) -> f64 {
|
||||
self.value
|
||||
}
|
||||
|
||||
pub fn set<T: Into<f64>>(&mut self, new_value: T) {
|
||||
self.value = new_value.into();
|
||||
self.clamp_to_bounds();
|
||||
}
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.value.abs() < f64::EPSILON
|
||||
}
|
||||
|
||||
pub fn is_one(&self) -> bool {
|
||||
(self.value - 1.0).abs() < f64::EPSILON
|
||||
}
|
||||
|
||||
fn clamp_to_bounds(&mut self) {
|
||||
self.value = if self.value > 1.0 {
|
||||
1.0
|
||||
} else if self.value < 0.0 {
|
||||
0.0
|
||||
} else {
|
||||
self.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<f64> for Proportion {
|
||||
fn as_ref(&self) -> &f64 {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Proportion {
|
||||
type Target = f64;
|
||||
fn deref(&self) -> &f64 {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialEq for Proportion {
|
||||
fn eq(&self, other: &Proportion) -> bool {
|
||||
self.value == other.value
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd for Proportion {
|
||||
fn partial_cmp(&self, other: &Proportion) -> Option<std::cmp::Ordering> {
|
||||
self.value.partial_cmp(&other.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::Eq for Proportion {}
|
||||
|
||||
impl std::cmp::Ord for Proportion {
|
||||
fn cmp(&self, other: &Proportion) -> std::cmp::Ordering {
|
||||
self.partial_cmp(&other).unwrap()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue