1use rust_decimal::Decimal;
2use std::fmt;
3use std::str::FromStr;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct Amount(Decimal);
8
9impl Amount {
10 pub const ZERO: Self = Self(Decimal::ZERO);
11
12 pub fn new(value: Decimal) -> Self {
13 Self(value.round_dp(2))
14 }
15
16 pub fn from_minor(cents: i64) -> Self {
17 Self(Decimal::new(cents, 2))
18 }
19
20 pub fn parse(s: &str) -> Result<Self, rust_decimal::Error> {
21 Ok(Self::new(Decimal::from_str(s)?))
22 }
23
24 pub fn raw(self) -> Decimal {
25 self.0
26 }
27
28 pub fn is_zero(self) -> bool {
29 self.0.is_zero()
30 }
31
32 pub fn saturating_add(self, other: Self) -> Self {
33 Self::new(self.0 + other.0)
34 }
35
36 pub fn saturating_sub(self, other: Self) -> Self {
37 Self::new(self.0 - other.0)
38 }
39}
40
41impl fmt::Display for Amount {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 write!(f, "{}", self.0.round_dp(2))
44 }
45}
46
47impl From<Decimal> for Amount {
48 fn from(value: Decimal) -> Self {
49 Self::new(value)
50 }
51}