Skip to main content

fastnum/decimal/
sign.rs

1use core::{
2    fmt,
3    fmt::{Display, Formatter},
4    hash::{Hash, Hasher},
5    ops::{Mul, Not},
6};
7
8/// A `Sign` represents `sign` associated with a decimal number.
9#[derive(Copy, Clone, Debug)]
10#[repr(u8)]
11pub enum Sign {
12    /// Positive: plus "+" or no sign.
13    Plus,
14
15    /// Negative: minus "-" sign.
16    Minus,
17}
18
19impl Sign {
20    /// Returns the default `Plus`.
21    #[inline(always)]
22    pub const fn default() -> Self {
23        Self::Plus
24    }
25
26    /// Returns `true` if sign is negative, and `false` otherwise.
27    #[inline(always)]
28    pub const fn is_negative(self) -> bool {
29        matches!(self, Self::Minus)
30    }
31
32    /// Tests for `self` and `other` signs to be equal, and is used by `==`
33    /// operator.
34    #[inline(always)]
35    pub const fn eq(&self, other: &Self) -> bool {
36        match (self, other) {
37            (Self::Plus, Self::Plus) => true,
38            (Self::Minus, Self::Minus) => true,
39            (_, _) => false,
40        }
41    }
42
43    /// Invert `Sign` value.
44    ///
45    /// # Example
46    ///
47    /// ```
48    /// use fastnum::decimal::Sign;
49    ///
50    /// assert_eq!(Sign::Plus.not(), Sign::Minus);
51    /// assert_eq!(Sign::Minus.not(), Sign::Plus);
52    /// ```
53    #[inline(always)]
54    pub const fn not(self) -> Self {
55        match self {
56            Sign::Minus => Sign::Plus,
57            Sign::Plus => Sign::Minus,
58        }
59    }
60
61    /// Sign "multiplication".
62    #[inline(always)]
63    pub const fn mul(self, rhs: Self) -> Self {
64        match (self, rhs) {
65            (Sign::Plus, Sign::Plus) => Sign::Plus,
66            (Sign::Minus, Sign::Minus) => Sign::Plus,
67            (_, _) => Sign::Minus,
68        }
69    }
70
71    /// Sign "division".
72    #[inline(always)]
73    pub const fn div(self, rhs: Self) -> Self {
74        self.mul(rhs)
75    }
76}
77
78impl Default for Sign {
79    fn default() -> Self {
80        Self::default()
81    }
82}
83
84impl PartialEq for Sign {
85    fn eq(&self, other: &Self) -> bool {
86        self.eq(other)
87    }
88}
89
90impl Eq for Sign {}
91
92impl Hash for Sign {
93    #[inline]
94    fn hash<H: Hasher>(&self, state: &mut H) {
95        let s = match self {
96            Sign::Minus => -1,
97            Sign::Plus => 1,
98        };
99        s.hash(state);
100    }
101}
102
103impl Not for Sign {
104    type Output = Sign;
105
106    #[inline]
107    fn not(self) -> Self::Output {
108        self.not()
109    }
110}
111
112impl Mul<Sign> for Sign {
113    type Output = Sign;
114
115    #[inline]
116    fn mul(self, other: Sign) -> Sign {
117        self.mul(other)
118    }
119}
120
121impl Display for Sign {
122    #[inline]
123    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
124        match self {
125            Sign::Minus => "-".fmt(f),
126            Sign::Plus => Ok(()),
127        }
128    }
129}