Skip to content

Commit

Permalink
Merge pull request #15 from volfco/main
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasK33 authored Jun 12, 2024
2 parents a6575c9 + 6c00305 commit acb8cb0
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "kube_quantity"
version = "0.7.1"
version = "0.8.0"

authors = ["Thomas Kosiewski <[email protected]>"]
description = "kube_quantity is a library adding arithmetic operations to the Quantity type from the k8s-openapi crate."
Expand Down
101 changes: 101 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@ impl From<ParsedQuantity> for Quantity {
#[cfg(test)]
mod tests {
use k8s_openapi::apimachinery::pkg::api::resource::Quantity;
use rust_decimal::Decimal;
use rust_decimal::prelude::FromPrimitive;

use crate::{ParseQuantityError, ParsedQuantity};
use crate::format::Format;
use crate::scale::Scale;

#[test]
fn test_quantity_addition() {
Expand Down Expand Up @@ -158,4 +162,101 @@ mod tests {
assert!(q.is_err());
assert_eq!(q.unwrap_err().to_string(), "quantity parsing failed");
}


#[test]
fn test_div() {
let exp_result = ParsedQuantity {
value: Decimal::from_f32(2.0).unwrap(),
scale: Scale::Kilo,
format: Format::BinarySI,
};

let q1 = ParsedQuantity {
value: Decimal::from_f32(4.0).unwrap(),
scale: Scale::Kilo,
format: Format::BinarySI,
};
let q2 = ParsedQuantity {
value: Decimal::from_f32(2.0).unwrap(),
scale: Scale::One,
format: Format::BinarySI,
};

let result = q1 / q2;

assert_eq!(result, exp_result);
}

#[test]
fn test_div_assign() {
let exp_result = ParsedQuantity {
value: Decimal::from_f32(2.0).unwrap(),
scale: Scale::Kilo,
format: Format::BinarySI,
};

let mut q1 = ParsedQuantity {
value: Decimal::from_f32(4.0).unwrap(),
scale: Scale::Kilo,
format: Format::BinarySI,
};
let q2 = ParsedQuantity {
value: Decimal::from_f32(2.0).unwrap(),
scale: Scale::One,
format: Format::BinarySI,
};

q1 /= q2;

assert_eq!(q1, exp_result);
}

#[test]
fn test_mul() {
let exp_result = ParsedQuantity {
value: Decimal::from_f32(8.0).unwrap(),
scale: Scale::Kilo,
format: Format::BinarySI,
};

let q1 = ParsedQuantity {
value: Decimal::from_f32(4.0).unwrap(),
scale: Scale::Kilo,
format: Format::BinarySI,
};
let q2 = ParsedQuantity {
value: Decimal::from_f32(2.0).unwrap(),
scale: Scale::One,
format: Format::BinarySI,
};

let result = q1 * q2;

assert_eq!(result, exp_result);
}

#[test]
fn test_mul_assign() {
let exp_result = ParsedQuantity {
value: Decimal::from_f32(8.0).unwrap(),
scale: Scale::Kilo,
format: Format::BinarySI,
};

let mut q1 = ParsedQuantity {
value: Decimal::from_f32(4.0).unwrap(),
scale: Scale::Kilo,
format: Format::BinarySI,
};
let q2 = ParsedQuantity {
value: Decimal::from_f32(2.0).unwrap(),
scale: Scale::One,
format: Format::BinarySI,
};

q1 *= q2;

assert_eq!(q1, exp_result);
}
}
78 changes: 77 additions & 1 deletion src/quantity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{
cmp::{Eq, Ord, PartialEq, PartialOrd},
default::Default,
fmt::Display,
ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign},
ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign, Div, DivAssign},
};

use rust_decimal::prelude::*;
Expand Down Expand Up @@ -102,6 +102,60 @@ impl Sub for ParsedQuantity {
}
}

impl Div for ParsedQuantity {
type Output = Self;

fn div(self, rhs: Self) -> Self::Output {
let mut lhs = self;
let mut rhs = rhs;

// Bring both quantities to the same format
// - If the formats are different, use the lhs format as output format and
// multiply the rhs value by the format multiplier
normalize_formats(&mut lhs, &mut rhs);

// Bring both scales to the same ones
// - If the scales are different, use the smaller scale as output scale
normalize_scales(&mut lhs, &mut rhs);

// Divide the normalized values
let value = lhs.value.div(rhs.value).normalize();

Self {
value,
scale: lhs.scale,
format: lhs.format,
}
}
}

impl Mul for ParsedQuantity {
type Output = Self;

fn mul(self, rhs: Self) -> Self::Output {
let mut lhs = self;
let mut rhs = rhs;

// Bring both quantities to the same format
// - If the formats are different, use the lhs format as output format and
// multiply the rhs value by the format multiplier
normalize_formats(&mut lhs, &mut rhs);

// Bring both scales to the same ones
// - If the scales are different, use the smaller scale as output scale
normalize_scales(&mut lhs, &mut rhs);

// Multiply the normalized values
let value = lhs.value.mul(rhs.value).normalize();

Self {
value,
scale: lhs.scale,
format: lhs.format,
}
}
}

impl Neg for ParsedQuantity {
type Output = Self;

Expand Down Expand Up @@ -136,6 +190,28 @@ impl SubAssign for ParsedQuantity {
}
}

impl MulAssign for ParsedQuantity {
fn mul_assign(&mut self, rhs: Self) {
let mut rhs = rhs;

normalize_formats(self, &mut rhs);
normalize_scales(self, &mut rhs);

self.value.mul_assign(rhs.value);
}
}

impl DivAssign for ParsedQuantity {
fn div_assign(&mut self, rhs: Self) {
let mut rhs = rhs;

normalize_formats(self, &mut rhs);
normalize_scales(self, &mut rhs);

self.value.div_assign(rhs.value);
}
}

impl PartialEq for ParsedQuantity {
fn eq(&self, other: &Self) -> bool {
let mut lhs = self.clone();
Expand Down

0 comments on commit acb8cb0

Please sign in to comment.