Skip to main content

teaql_tool_std/
decimal.rs

1use rust_decimal::Decimal;
2use rust_decimal::RoundingStrategy;
3use std::str::FromStr;
4use teaql_tool_core::{Result, TeaQLToolError};
5
6pub struct DecimalTool;
7
8impl DecimalTool {
9    pub fn new() -> Self {
10        Self
11    }
12
13    pub fn of(&self, s: &str) -> Result<Decimal> {
14        Decimal::from_str(s).map_err(|e| TeaQLToolError::ParseError(e.to_string()))
15    }
16
17    pub fn zero(&self) -> Decimal {
18        Decimal::ZERO
19    }
20
21    pub fn one(&self) -> Decimal {
22        Decimal::ONE
23    }
24
25    pub fn add(&self, a: Decimal, b: Decimal) -> Decimal {
26        a + b
27    }
28
29    pub fn sub(&self, a: Decimal, b: Decimal) -> Decimal {
30        a - b
31    }
32
33    pub fn mul(&self, a: Decimal, b: Decimal) -> Decimal {
34        a * b
35    }
36
37    pub fn div(&self, a: Decimal, b: Decimal) -> Result<Decimal> {
38        if b.is_zero() {
39            Err(TeaQLToolError::InvalidArgument(
40                "Division by zero".to_string(),
41            ))
42        } else {
43            Ok(a / b)
44        }
45    }
46
47    pub fn round(&self, a: Decimal, dp: u32) -> Decimal {
48        a.round_dp_with_strategy(dp, RoundingStrategy::MidpointNearestEven)
49    }
50
51    pub fn ceil(&self, a: Decimal) -> Decimal {
52        a.ceil()
53    }
54
55    pub fn floor(&self, a: Decimal) -> Decimal {
56        a.floor()
57    }
58
59    pub fn abs(&self, a: Decimal) -> Decimal {
60        a.abs()
61    }
62
63    pub fn min(&self, a: Decimal, b: Decimal) -> Decimal {
64        a.min(b)
65    }
66
67    pub fn max(&self, a: Decimal, b: Decimal) -> Decimal {
68        a.max(b)
69    }
70
71    pub fn percent(&self, amount: Decimal, pct: Decimal) -> Decimal {
72        (amount * pct) / Decimal::from(100)
73    }
74
75    pub fn ratio(&self, part: Decimal, total: Decimal) -> Result<Decimal> {
76        self.div(part, total)
77    }
78}
79
80impl Default for DecimalTool {
81    fn default() -> Self {
82        Self::new()
83    }
84}