bullet_exchange_interface/decimals/
fixed_positive_decimal.rs1use super::{PositiveDecimal, RoundingMode};
2
3pub const FIXED_DECIMALS: u32 = 12;
4
5#[derive(
6 Default,
7 Debug,
8 Clone,
9 Copy,
10 PartialEq,
11 Eq,
12 PartialOrd,
13 Ord,
14 serde::Serialize,
15 serde::Deserialize,
16 borsh::BorshSerialize,
17 borsh::BorshDeserialize,
18)]
19#[cfg_attr(feature = "schema", derive(sov_universal_wallet::UniversalWallet))]
20#[serde(transparent)]
21pub struct FixedPositiveDecimal(PositiveDecimal);
22
23impl std::fmt::Display for FixedPositiveDecimal {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 write!(f, "{}", self.0)
26 }
27}
28
29impl From<PositiveDecimal> for FixedPositiveDecimal {
30 fn from(value: PositiveDecimal) -> Self {
31 Self::new(value, RoundingMode::Down)
32 }
33}
34
35impl From<FixedPositiveDecimal> for PositiveDecimal {
36 fn from(value: FixedPositiveDecimal) -> PositiveDecimal {
37 value.0
38 }
39}
40
41impl FixedPositiveDecimal {
42 pub const ZERO: FixedPositiveDecimal = FixedPositiveDecimal(PositiveDecimal::ZERO);
43
44 #[inline]
45 pub fn new(value: PositiveDecimal, mode: RoundingMode) -> Self {
46 let rounded = match mode {
47 RoundingMode::Up => value.as_dec().round_dp_with_strategy(
48 FIXED_DECIMALS,
49 rust_decimal::RoundingStrategy::AwayFromZero,
50 ),
51 RoundingMode::Down => value
52 .as_dec()
53 .round_dp_with_strategy(FIXED_DECIMALS, rust_decimal::RoundingStrategy::ToZero),
54 };
55
56 #[allow(
61 clippy::expect_used,
62 reason = "Rounding down a PositiveDecimal is infallible - result is always non-negative"
63 )]
64 Self(
65 PositiveDecimal::new(rounded).expect(
66 "rounding down a PositiveDecimal always produces valid FixedPositiveDecimal",
67 ),
68 )
69 }
70
71 #[inline(always)]
72 pub fn is_zero(&self) -> bool {
73 self.0.is_zero()
74 }
75
76 #[inline(always)]
77 pub fn as_pos_dec(&self) -> PositiveDecimal {
78 self.0
79 }
80}