Skip to main content

nexus_decimal/
constants.rs

1//! Named constants for common decimal values.
2//!
3//! Core constants (`ZERO`, `ONE`, `MAX`, `MIN`) are generated for each
4//! backing type. Financial constants (CENT, BASIS_POINT, etc.) are
5//! in `financial.rs`.
6
7use crate::Decimal;
8
9macro_rules! impl_decimal_constants {
10    ($backing:ty) => {
11        impl<const D: u8> Decimal<$backing, D> {
12            /// Zero (`0`).
13            pub const ZERO: Self = Self { value: 0 };
14
15            /// One (`1.0`).
16            pub const ONE: Self = Self { value: Self::SCALE };
17
18            /// Negative one (`-1.0`).
19            pub const NEG_ONE: Self = Self {
20                value: -Self::SCALE,
21            };
22
23            /// Maximum representable value.
24            pub const MAX: Self = Self {
25                value: <$backing>::MAX,
26            };
27
28            /// Minimum representable value.
29            pub const MIN: Self = Self {
30                value: <$backing>::MIN,
31            };
32
33            /// Smallest positive representable value (`from_raw(1)`).
34            ///
35            /// Represents `1 / 10^D` — the resolution of this decimal type.
36            pub const EPSILON: Self = Self { value: 1 };
37
38            /// One half (`0.5`).
39            ///
40            /// # Compile-time constraint
41            ///
42            /// Requires `D >= 1`. Referencing `HALF` on a `Decimal` with
43            /// `D = 0` is a compile error — the value 0.5 is not
44            /// representable with zero fractional digits.
45            pub const HALF: Self = {
46                assert!(
47                    D >= 1,
48                    "HALF requires D >= 1: 0.5 is not representable with zero fractional digits"
49                );
50                Self {
51                    value: Self::SCALE / 2,
52                }
53            };
54
55            /// One basis point (`0.0001`).
56            ///
57            /// # Compile-time constraint
58            ///
59            /// Requires `D >= 4`. Referencing `BASIS_POINT` on a `Decimal`
60            /// with fewer than 4 fractional digits is a compile error.
61            pub const BASIS_POINT: Self = {
62                assert!(
63                    D >= 4,
64                    "BASIS_POINT requires D >= 4: 0.0001 is not representable with fewer than 4 fractional digits"
65                );
66                Self {
67                    value: Self::SCALE / 10000,
68                }
69            };
70
71            /// Two (`2.0`).
72            ///
73            /// # Compile-time constraint
74            ///
75            /// Requires the backing type to be wide enough that `2 * SCALE`
76            /// does not overflow. This holds for all valid `D` on `i32` and
77            /// `i64`; on `i128` it fails at `D = 38`.
78            pub const TWO: Self = {
79                assert!(
80                    Self::SCALE <= <$backing>::MAX / 2,
81                    "TWO requires 2*SCALE to fit in the backing type"
82                );
83                Self {
84                    value: Self::SCALE * 2,
85                }
86            };
87        }
88    };
89}
90
91impl_decimal_constants!(i32);
92impl_decimal_constants!(i64);
93impl_decimal_constants!(i128);