feat: convert price from major to minor and minor to major #106
4 changed files with 44 additions and 78 deletions
|
@ -46,6 +46,22 @@ pub struct Price {
|
||||||
currency: Currency,
|
currency: Currency,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Price {
|
||||||
|
pub fn major_as_minor(&self) -> usize {
|
||||||
|
self.major * 100
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_minor(minor_only: usize, currency: Currency) -> Price {
|
||||||
|
let minor = minor_only % 100;
|
||||||
|
let major = (minor_only - minor) / 100;
|
||||||
|
Price {
|
||||||
|
minor,
|
||||||
|
major,
|
||||||
|
currency,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -69,4 +85,29 @@ mod tests {
|
||||||
fn currency_to_string_from_str() {
|
fn currency_to_string_from_str() {
|
||||||
assert!(test_helper(Currency::INR, INR));
|
assert!(test_helper(Currency::INR, INR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_major_to_minor() {
|
||||||
|
assert_eq!(
|
||||||
|
Price {
|
||||||
|
major: 100,
|
||||||
|
minor: 0,
|
||||||
|
currency: Currency::INR,
|
||||||
|
}
|
||||||
|
.major_as_minor(),
|
||||||
|
100 * 100
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_minor() {
|
||||||
|
assert_eq!(
|
||||||
|
Price::from_minor((100 * 100) + 1, Currency::INR),
|
||||||
|
Price {
|
||||||
|
major: 100,
|
||||||
|
minor: 1,
|
||||||
|
currency: Currency::INR,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
// error cases
|
// error cases
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
QuantityPart {
|
QuantityPart {
|
||||||
unit: QuantityUnit::Milligram,
|
unit: QuantityUnit::Milligram,
|
||||||
number: 1
|
number: 1
|
||||||
|
@ -268,7 +268,7 @@ mod tests {
|
||||||
.as_minor(),
|
.as_minor(),
|
||||||
Err(QuantityError::QuantityCantBeDivided)
|
Err(QuantityError::QuantityCantBeDivided)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
QuantityPart {
|
QuantityPart {
|
||||||
unit: QuantityUnit::DiscreteNumber,
|
unit: QuantityUnit::DiscreteNumber,
|
||||||
number: 1
|
number: 1
|
||||||
|
@ -276,7 +276,7 @@ mod tests {
|
||||||
.as_minor(),
|
.as_minor(),
|
||||||
Err(QuantityError::QuantityCantBeDivided)
|
Err(QuantityError::QuantityCantBeDivided)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
QuantityPart {
|
QuantityPart {
|
||||||
unit: QuantityUnit::Milligram,
|
unit: QuantityUnit::Milligram,
|
||||||
number: 1
|
number: 1
|
||||||
|
@ -284,7 +284,5 @@ mod tests {
|
||||||
.as_minor(),
|
.as_minor(),
|
||||||
Err(QuantityError::QuantityCantBeDivided)
|
Err(QuantityError::QuantityCantBeDivided)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use cqrs_es::Aggregate;
|
|
||||||
use derive_builder::Builder;
|
|
||||||
use derive_getters::Getters;
|
|
||||||
use derive_more::Display;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[derive(Clone, Display, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
|
|
||||||
pub enum Currency {
|
|
||||||
#[display(fmt = "{}", INR)]
|
|
||||||
INR,
|
|
||||||
}
|
|
||||||
|
|
||||||
const INR: &str = "INR";
|
|
||||||
|
|
||||||
impl FromStr for Currency {
|
|
||||||
type Err = String;
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
let s = s.trim();
|
|
||||||
match s {
|
|
||||||
INR => Ok(Self::INR),
|
|
||||||
_ => Err("Currency unsupported".into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Currency {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::INR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(
|
|
||||||
Clone, Default, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters, Builder,
|
|
||||||
)]
|
|
||||||
pub struct Price {
|
|
||||||
major: usize,
|
|
||||||
minor: usize,
|
|
||||||
currency: Currency,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
fn test_helper<T>(t: T, str_value: &str) -> bool
|
|
||||||
where
|
|
||||||
T: ToString + FromStr + std::fmt::Debug + PartialEq,
|
|
||||||
<T as FromStr>::Err: std::fmt::Debug,
|
|
||||||
{
|
|
||||||
println!("Testing type: {:?} against value {str_value}", t);
|
|
||||||
assert_eq!(t.to_string(), str_value.to_string());
|
|
||||||
|
|
||||||
assert_eq!(T::from_str(str_value).unwrap(), t);
|
|
||||||
|
|
||||||
assert_eq!(T::from_str(t.to_string().as_str()).unwrap(), t,);
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn currency_to_string_from_str() {
|
|
||||||
assert!(test_helper(Currency::INR, INR));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
pub mod currency;
|
|
||||||
pub mod parse_aggregate_id;
|
pub mod parse_aggregate_id;
|
||||||
pub mod random_string;
|
pub mod random_string;
|
||||||
pub mod string;
|
pub mod string;
|
||||||
|
|
Loading…
Reference in a new issue