Skip to main content

bullet_exchange_interface/decimals/
ops.rs

1use std::str::FromStr;
2
3use rust_decimal::{Decimal, MathematicalOps};
4
5use crate::error::{ArithmeticError, ArithmeticOperation, ConfigError};
6
7pub trait TryDecimalOps {
8    fn try_from_str(value: &str) -> Result<Self, ConfigError>
9    where
10        Self: Sized;
11    fn try_add(self, v: impl Into<Decimal>) -> Result<Self, ArithmeticError>
12    where
13        Self: Sized;
14    fn try_sub(self, v: impl Into<Decimal>) -> Result<Self, ArithmeticError>
15    where
16        Self: Sized;
17    fn try_mul(self, v: impl Into<Decimal>) -> Result<Self, ArithmeticError>
18    where
19        Self: Sized;
20    fn try_div(self, v: impl Into<Decimal>) -> Result<Self, ArithmeticError>
21    where
22        Self: Sized;
23    fn try_exp(self) -> Result<Self, ArithmeticError>
24    where
25        Self: Sized;
26}
27
28impl TryDecimalOps for Decimal {
29    #[inline]
30    fn try_from_str(value: &str) -> Result<Self, ConfigError> {
31        Decimal::from_str(value).map_err(|_| ConfigError::FailedToParseInput {
32            input: value.to_string(),
33            reason: format!(
34                "Provided string value for {value} cannot be converted to the underlying type (Decimal)",
35            )
36	})
37    }
38
39    #[inline]
40    fn try_add(self, v: impl Into<Decimal>) -> Result<Self, ArithmeticError> {
41        let v = v.into();
42        self.checked_add(v).ok_or(ArithmeticError::DecimalFailed {
43            operation: ArithmeticOperation::Addition,
44            left: self,
45            right: v,
46        })
47    }
48
49    #[inline]
50    fn try_sub(self, v: impl Into<Decimal>) -> Result<Self, ArithmeticError> {
51        let v = v.into();
52        self.checked_sub(v).ok_or(ArithmeticError::DecimalFailed {
53            operation: ArithmeticOperation::Subtraction,
54            left: self,
55            right: v,
56        })
57    }
58
59    #[inline]
60    fn try_mul(self, v: impl Into<Decimal>) -> Result<Self, ArithmeticError> {
61        let v = v.into();
62        self.checked_mul(v).ok_or(ArithmeticError::DecimalFailed {
63            operation: ArithmeticOperation::Multiplication,
64            left: self,
65            right: v,
66        })
67    }
68
69    #[inline]
70    fn try_div(self, v: impl Into<Decimal>) -> Result<Self, ArithmeticError> {
71        let v = v.into();
72        self.checked_div(v).ok_or(ArithmeticError::DecimalFailed {
73            operation: ArithmeticOperation::Division,
74            left: self,
75            right: v,
76        })
77    }
78
79    #[inline]
80    fn try_exp(self) -> Result<Self, ArithmeticError> {
81        self.checked_exp().ok_or(ArithmeticError::DecimalFailed {
82            operation: ArithmeticOperation::Exponentiation,
83            left: self,
84            right: Decimal::ZERO,
85        })
86    }
87}