feat: convert quantity to minor
This commit is contained in:
parent
83f0726bae
commit
3a6b200773
1 changed files with 93 additions and 1 deletions
|
@ -6,7 +6,7 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use derive_builder::Builder;
|
use derive_builder::Builder;
|
||||||
use derive_getters::Getters;
|
use derive_getters::Getters;
|
||||||
use derive_more::Display;
|
use derive_more::{Display, Error};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
@ -17,6 +17,9 @@ pub enum QuantityUnit {
|
||||||
Kilogram,
|
Kilogram,
|
||||||
#[display(fmt = "{}", GRAM)]
|
#[display(fmt = "{}", GRAM)]
|
||||||
Gram,
|
Gram,
|
||||||
|
#[display(fmt = "{}", MILLI_GRAM)]
|
||||||
|
Milligram,
|
||||||
|
|
||||||
#[default]
|
#[default]
|
||||||
#[display(fmt = "{}", DISCRETE_NUMBER)]
|
#[display(fmt = "{}", DISCRETE_NUMBER)]
|
||||||
DiscreteNumber, // example: 1 sofa, 2 bed, etc.
|
DiscreteNumber, // example: 1 sofa, 2 bed, etc.
|
||||||
|
@ -28,6 +31,7 @@ pub enum QuantityUnit {
|
||||||
|
|
||||||
const KILO_GRAM: &str = "kg";
|
const KILO_GRAM: &str = "kg";
|
||||||
const GRAM: &str = "g";
|
const GRAM: &str = "g";
|
||||||
|
const MILLI_GRAM: &str = "mg";
|
||||||
const DISCRETE_NUMBER: &str = "discrete_number";
|
const DISCRETE_NUMBER: &str = "discrete_number";
|
||||||
const MILLI_LITER: &str = "ml";
|
const MILLI_LITER: &str = "ml";
|
||||||
const LITER: &str = "l";
|
const LITER: &str = "l";
|
||||||
|
@ -41,6 +45,7 @@ impl FromStr for QuantityUnit {
|
||||||
DISCRETE_NUMBER => Ok(Self::DiscreteNumber),
|
DISCRETE_NUMBER => Ok(Self::DiscreteNumber),
|
||||||
MILLI_LITER => Ok(Self::MilliLiter),
|
MILLI_LITER => Ok(Self::MilliLiter),
|
||||||
LITER => Ok(Self::Liter),
|
LITER => Ok(Self::Liter),
|
||||||
|
MILLI_GRAM => Ok(Self::Milligram),
|
||||||
_ => Err("Currency unsupported".into()),
|
_ => Err("Currency unsupported".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +63,17 @@ impl QuantityPart {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.number == 0
|
self.number == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_minor(&self) -> QuantityResult<usize> {
|
||||||
|
match self.unit {
|
||||||
|
QuantityUnit::Kilogram | QuantityUnit::Liter | QuantityUnit::Gram => {
|
||||||
|
Ok(self.number * 1000)
|
||||||
|
}
|
||||||
|
QuantityUnit::Milligram | QuantityUnit::MilliLiter | QuantityUnit::DiscreteNumber => {
|
||||||
|
Err(QuantityError::QuantityCantBeDivided)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
@ -67,11 +83,21 @@ pub struct Quantity {
|
||||||
minor: QuantityPart,
|
minor: QuantityPart,
|
||||||
major: QuantityPart,
|
major: QuantityPart,
|
||||||
}
|
}
|
||||||
|
pub type QuantityResult<V> = Result<V, QuantityError>;
|
||||||
|
|
||||||
|
#[derive(Debug, Error, Display, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum QuantityError {
|
||||||
|
QuantityCantBeDivided,
|
||||||
|
}
|
||||||
|
|
||||||
impl Quantity {
|
impl Quantity {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.minor.is_empty() == true && self.major.is_empty() == true
|
self.minor.is_empty() == true && self.major.is_empty() == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn major_as_minor(&self) -> QuantityResult<usize> {
|
||||||
|
self.major.as_minor()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -180,6 +206,11 @@ mod tests {
|
||||||
assert!(test_helper(QuantityUnit::Liter, LITER));
|
assert!(test_helper(QuantityUnit::Liter, LITER));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn quantity_unit_milli_gram() {
|
||||||
|
assert!(test_helper(QuantityUnit::Milligram, MILLI_GRAM));
|
||||||
|
}
|
||||||
|
|
||||||
impl Quantity {
|
impl Quantity {
|
||||||
pub fn get_quantity() -> Self {
|
pub fn get_quantity() -> Self {
|
||||||
let q = QuantityPartBuilder::default()
|
let q = QuantityPartBuilder::default()
|
||||||
|
@ -195,4 +226,65 @@ mod tests {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_quantity_as_minor() {
|
||||||
|
assert_eq!(
|
||||||
|
QuantityPart {
|
||||||
|
unit: QuantityUnit::Kilogram,
|
||||||
|
number: 1
|
||||||
|
}
|
||||||
|
.as_minor()
|
||||||
|
.unwrap(),
|
||||||
|
1000
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
QuantityPart {
|
||||||
|
unit: QuantityUnit::Gram,
|
||||||
|
number: 1
|
||||||
|
}
|
||||||
|
.as_minor()
|
||||||
|
.unwrap(),
|
||||||
|
1000
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
QuantityPart {
|
||||||
|
unit: QuantityUnit::Liter,
|
||||||
|
number: 1
|
||||||
|
}
|
||||||
|
.as_minor()
|
||||||
|
.unwrap(),
|
||||||
|
1000
|
||||||
|
);
|
||||||
|
|
||||||
|
// error cases
|
||||||
|
assert_eq!(
|
||||||
|
QuantityPart {
|
||||||
|
unit: QuantityUnit::Milligram,
|
||||||
|
number: 1
|
||||||
|
}
|
||||||
|
.as_minor(),
|
||||||
|
Err(QuantityError::QuantityCantBeDivided)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
QuantityPart {
|
||||||
|
unit: QuantityUnit::DiscreteNumber,
|
||||||
|
number: 1
|
||||||
|
}
|
||||||
|
.as_minor(),
|
||||||
|
Err(QuantityError::QuantityCantBeDivided)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
QuantityPart {
|
||||||
|
unit: QuantityUnit::Milligram,
|
||||||
|
number: 1
|
||||||
|
}
|
||||||
|
.as_minor(),
|
||||||
|
Err(QuantityError::QuantityCantBeDivided)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue