use std::{fmt::Display, ops};
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug, serde::Serialize, serde::Deserialize)]
pub struct Cent(pub f64);
impl Cent {
pub(crate) fn abs(&self) -> Self {
Cent(self.0.abs())
}
}
impl Display for Cent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.0, f)?;
f.write_str(" cents")
}
}
impl ops::Add for Cent {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Cent(self.0.add(rhs.0))
}
}
impl ops::Add<f64> for Cent {
type Output = Self;
fn add(self, rhs: f64) -> Self::Output {
Self(self.0 + rhs)
}
}
impl ops::Sub<f64> for Cent {
type Output = Self;
fn sub(self, rhs: f64) -> Self::Output {
Self(self.0 - rhs)
}
}
impl ops::Div<u32> for Cent {
type Output = Self;
fn div(self, rhs: u32) -> Self::Output {
Self(self.0 / (rhs as f64))
}
}
impl ops::Div<f64> for Cent {
type Output = Self;
fn div(self, rhs: f64) -> Self::Output {
Self(self.0 / rhs)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn check_adding_cents_with_cents() {
assert_eq!(Cent(0.0) + Cent(1.0), Cent(1.0));
assert_eq!(Cent(1.0) + Cent(0.0), Cent(1.0));
assert_eq!(Cent(1.0) + Cent(2.0), Cent(3.0));
assert_eq!(Cent(-1.0) + Cent(2.0), Cent(1.0));
assert_eq!(Cent(1.0) + Cent(2.0), Cent(3.0));
assert_eq!(Cent(-1.0) + Cent(-1.0), Cent(-2.0));
}
#[test]
fn check_adding_cents_with_float() {
assert_eq!(Cent(0.0) + 1.0, Cent(1.0));
assert_eq!(Cent(1.0) + 0.0, Cent(1.0));
assert_eq!(Cent(1.0) + 2.0, Cent(3.0));
assert_eq!(Cent(-1.0) + 2.0, Cent(1.0));
assert_eq!(Cent(1.0) + 2.0, Cent(3.0));
assert_eq!(Cent(-1.0) + -1.0, Cent(-2.0));
}
#[test]
fn check_subtractinging_cents_with_float() {
assert_eq!(Cent(0.0) - 1.0, Cent(-1.0));
assert_eq!(Cent(1.0) - 0.0, Cent(1.0));
assert_eq!(Cent(1.0) - 2.0, Cent(-1.0));
assert_eq!(Cent(-1.0) - 2.0, Cent(-3.0));
assert_eq!(Cent(1.0) - 2.0, Cent(-1.0));
assert_eq!(Cent(-1.0) - -1.0, Cent(0.0));
}
}