/rust/registry/src/index.crates.io-1949cf8c6b5b557f/fastnum-0.3.2/src/decimal/context.rs
Line | Count | Source |
1 | | mod rounding_mode; |
2 | | mod signal_traps; |
3 | | |
4 | | pub use rounding_mode::RoundingMode; |
5 | | pub use signal_traps::SignalsTraps; |
6 | | |
7 | | use core::fmt::{Debug, Display, Formatter}; |
8 | | |
9 | | use crate::utils::assert_eq_size; |
10 | | |
11 | | /// # Decimal Context |
12 | | /// |
13 | | /// The context represents the user-selectable parameters and rules which govern |
14 | | /// the results of arithmetic operations (for example, the rounding mode when |
15 | | /// rounding occurs). |
16 | | #[derive(Copy, Clone, Hash, Eq, PartialEq)] |
17 | | #[repr(C)] |
18 | | pub struct Context { |
19 | | rounding_mode: RoundingMode, |
20 | | signal_traps: SignalsTraps, |
21 | | } |
22 | | |
23 | | impl Context { |
24 | | const DEFAULT: Self = Self { |
25 | | rounding_mode: RoundingMode::default(), |
26 | | signal_traps: SignalsTraps::default(), |
27 | | }; |
28 | | |
29 | | /// Returns the [Default Decimal Context](#crate::default-decimal-context). |
30 | | #[inline(always)] |
31 | | #[must_use] |
32 | 0 | pub const fn default() -> Self { |
33 | 0 | Self::DEFAULT |
34 | 0 | } |
35 | | |
36 | | /// Apply the given [RoundingMode] to the `Context`. |
37 | | #[must_use] |
38 | | #[inline(always)] |
39 | 0 | pub const fn with_rounding_mode(mut self, rm: RoundingMode) -> Self { |
40 | 0 | self.rounding_mode = rm; |
41 | 0 | self |
42 | 0 | } |
43 | | |
44 | | /// Apply no traps to given `Context`. |
45 | | #[inline(always)] |
46 | | #[must_use] |
47 | 0 | pub const fn without_traps(mut self) -> Self { |
48 | 0 | self.signal_traps = SignalsTraps::empty(); |
49 | 0 | self |
50 | 0 | } |
51 | | |
52 | | /// Method applies specified [SignalsTraps] to the given context. |
53 | | /// # Examples |
54 | | /// |
55 | | /// ``` |
56 | | /// use fastnum::{*, decimal::*}; |
57 | | /// |
58 | | /// let ctx = Context::default().without_traps(); |
59 | | /// |
60 | | /// // No panic! We can divide by zero! |
61 | | /// let res = dec256!(1.0).with_ctx(ctx) / dec256!(0).with_ctx(ctx); |
62 | | /// |
63 | | /// assert!(res.is_infinite()); |
64 | | /// assert!(res.is_op_div_by_zero()); |
65 | | /// assert!(res.is_op_invalid()); |
66 | | /// ``` |
67 | | #[must_use] |
68 | | #[inline(always)] |
69 | 0 | pub const fn with_signal_traps(mut self, traps: SignalsTraps) -> Self { |
70 | 0 | self.signal_traps = traps; |
71 | 0 | self |
72 | 0 | } |
73 | | |
74 | | /// Get [RoundingMode] of given `Context`. |
75 | | #[must_use] |
76 | | #[inline(always)] |
77 | 0 | pub const fn rounding_mode(&self) -> RoundingMode { |
78 | 0 | self.rounding_mode |
79 | 0 | } |
80 | | |
81 | | /// Get [SignalsTraps] of given `Context`. |
82 | | #[must_use] |
83 | | #[inline(always)] |
84 | 0 | pub const fn signal_traps(&self) -> SignalsTraps { |
85 | 0 | self.signal_traps |
86 | 0 | } |
87 | | |
88 | | #[inline(always)] |
89 | 0 | pub(crate) const fn new(rounding_mode: RoundingMode, signal_traps: SignalsTraps) -> Self { |
90 | 0 | Self { |
91 | 0 | rounding_mode, |
92 | 0 | signal_traps, |
93 | 0 | } |
94 | 0 | } |
95 | | |
96 | | #[inline(always)] |
97 | 0 | pub(crate) const fn merge(mut self, other: Self) -> Self { |
98 | 0 | self.signal_traps = self.signal_traps.merge(other.signal_traps); |
99 | | |
100 | 0 | if !other.rounding_mode.is_default() { |
101 | 0 | self.rounding_mode = other.rounding_mode; |
102 | 0 | } |
103 | | |
104 | 0 | self |
105 | 0 | } |
106 | | } |
107 | | |
108 | | impl Display for Context { |
109 | 0 | fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { |
110 | 0 | write!(f, "R={}, S={}", self.rounding_mode, self.signal_traps) |
111 | 0 | } |
112 | | } |
113 | | |
114 | | impl Debug for Context { |
115 | 0 | fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { |
116 | 0 | write!(f, "{self}") |
117 | 0 | } |
118 | | } |
119 | | |
120 | | assert_eq_size!(Context, u16); |