1 #![allow(deprecated, clippy::missing_const_for_fn)]
2 
3 use core::ops::{Div, DivAssign, Mul, MulAssign, Neg, Not};
4 #[cfg(feature = "serde")]
5 use standback::convert::TryInto;
6 use Sign::{Negative, Positive, Zero};
7 
8 /// Contains the sign of a value: positive, negative, or zero.
9 ///
10 /// For ease of use, `Sign` implements [`Mul`] and [`Div`] on all signed numeric
11 /// types. `Sign`s can also be multiplied and divided by another `Sign`, which
12 /// follows the same rules as real numbers.
13 #[repr(i8)]
14 #[cfg_attr(feature = "serde", derive(serde::Serialize))]
15 #[cfg_attr(feature = "serde", serde(into = "crate::serde::Sign"))]
16 #[deprecated(
17     since = "0.2.7",
18     note = "The only use for this (obtaining the sign of a `Duration`) can be replaced with \
19             `Duration::is_{positive|negative|zero}`"
20 )]
21 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
22 pub enum Sign {
23     /// A positive value.
24     Positive = 1,
25 
26     /// A negative value.
27     Negative = -1,
28 
29     /// A value that is exactly zero.
30     Zero = 0,
31 }
32 
33 #[cfg(feature = "serde")]
34 impl<'a> serde::Deserialize<'a> for Sign {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'a>,35     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
36     where
37         D: serde::Deserializer<'a>,
38     {
39         crate::serde::Sign::deserialize(deserializer)?
40             .try_into()
41             .map_err(serde::de::Error::custom)
42     }
43 }
44 impl Default for Sign {
45     /// `Sign` defaults to `Zero`.
46     ///
47     /// ```rust
48     /// # #![allow(deprecated)]
49     /// # use time::Sign;
50     /// assert_eq!(Sign::default(), Sign::Zero);
51     /// ```
default() -> Self52     fn default() -> Self {
53         Zero
54     }
55 }
56 
57 macro_rules! sign_mul {
58     ($($type:ty),+ $(,)?) => {
59         $(
60             impl Mul<$type> for Sign {
61                 type Output = $type;
62 
63                 #[allow(trivial_numeric_casts)]
64                 fn mul(self, rhs: $type) -> Self::Output {
65                     (self as i8) as $type * rhs
66                 }
67             }
68 
69             impl Mul<Sign> for $type {
70                 type Output = Self;
71 
72                 fn mul(self, rhs: Sign) -> Self::Output {
73                     rhs * self
74                 }
75             }
76 
77             impl MulAssign<Sign> for $type {
78                 #[allow(trivial_numeric_casts)]
79                 fn mul_assign(&mut self, rhs: Sign) {
80                     *self *= rhs as i8 as $type;
81                 }
82             }
83 
84             impl Div<Sign> for $type {
85                 type Output = Self;
86 
87                 fn div(self, rhs: Sign) -> Self::Output {
88                     self * rhs
89                 }
90             }
91 
92             impl DivAssign<Sign> for $type {
93                 fn div_assign(&mut self, rhs: Sign) {
94                     *self *= rhs
95                 }
96             }
97         )*
98     };
99 }
100 sign_mul![i8, i16, i32, i64, i128, f32, f64];
101 
102 impl Mul<Sign> for Sign {
103     type Output = Self;
104 
mul(self, rhs: Self) -> Self::Output105     fn mul(self, rhs: Self) -> Self::Output {
106         match (self, rhs) {
107             (Zero, _) | (_, Zero) => Zero,
108             (Positive, Positive) | (Negative, Negative) => Positive,
109             (Positive, Negative) | (Negative, Positive) => Negative,
110         }
111     }
112 }
113 
114 impl MulAssign<Sign> for Sign {
mul_assign(&mut self, rhs: Self)115     fn mul_assign(&mut self, rhs: Self) {
116         *self = *self * rhs;
117     }
118 }
119 
120 impl Div<Sign> for Sign {
121     type Output = Self;
122 
div(self, rhs: Self) -> Self::Output123     fn div(self, rhs: Self) -> Self::Output {
124         self * rhs
125     }
126 }
127 
128 impl DivAssign<Sign> for Sign {
div_assign(&mut self, rhs: Self)129     fn div_assign(&mut self, rhs: Self) {
130         *self *= rhs
131     }
132 }
133 
134 impl Neg for Sign {
135     type Output = Self;
136 
neg(self) -> Self::Output137     fn neg(self) -> Self::Output {
138         self.negate()
139     }
140 }
141 
142 impl Not for Sign {
143     type Output = Self;
144 
not(self) -> Self::Output145     fn not(self) -> Self::Output {
146         self.negate()
147     }
148 }
149 
150 impl Sign {
151     /// Return the opposite of the current sign.
152     ///
153     /// ```rust
154     /// # #![allow(deprecated)]
155     /// # use time::Sign;
156     /// assert_eq!(Sign::Positive.negate(), Sign::Negative);
157     /// assert_eq!(Sign::Negative.negate(), Sign::Positive);
158     /// assert_eq!(Sign::Zero.negate(), Sign::Zero);
159     /// ```
negate(self) -> Self160     pub fn negate(self) -> Self {
161         match self {
162             Positive => Negative,
163             Negative => Positive,
164             Zero => Zero,
165         }
166     }
167 
168     /// Is the sign positive?
169     ///
170     /// ```rust
171     /// # #![allow(deprecated)]
172     /// # use time::Sign;
173     /// assert!(Sign::Positive.is_positive());
174     /// assert!(!Sign::Negative.is_positive());
175     /// assert!(!Sign::Zero.is_positive());
176     /// ```
is_positive(self) -> bool177     pub const fn is_positive(self) -> bool {
178         self as u8 == Positive as u8
179     }
180 
181     /// Is the sign negative?
182     ///
183     /// ```rust
184     /// # #![allow(deprecated)]
185     /// # use time::Sign;
186     /// assert!(!Sign::Positive.is_negative());
187     /// assert!(Sign::Negative.is_negative());
188     /// assert!(!Sign::Zero.is_negative());
189     /// ```
is_negative(self) -> bool190     pub const fn is_negative(self) -> bool {
191         self as u8 == Negative as u8
192     }
193 
194     /// Is the value exactly zero?
195     ///
196     /// ```rust
197     /// # #![allow(deprecated)]
198     /// # use time::Sign;
199     /// assert!(!Sign::Positive.is_zero());
200     /// assert!(!Sign::Negative.is_zero());
201     /// assert!(Sign::Zero.is_zero());
202     /// ```
is_zero(self) -> bool203     pub const fn is_zero(self) -> bool {
204         self as u8 == Zero as u8
205     }
206 }
207