feat: convert price from major to minor and minor to major #106

Merged
realaravinth merged 1 commit from convert-price into master 2024-09-16 16:22:30 +05:30
4 changed files with 44 additions and 78 deletions

View file

@ -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,
}
);
}
} }

View file

@ -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)
); );
} }
} }

View file

@ -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));
}
}

View file

@ -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;