teaql_tool_std/
decimal.rs1use 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}