arithmetic_sign/
lib.rs

1pub mod error;
2pub mod prelude;
3use error::ArithmeticSignError;
4use std::convert::TryFrom;
5
6/// Negative or Positive for sign marking and sign part calculations
7/// note: Need `use std::convert::TryFrom` if you want to use `TryFrom<f32>` or `TryFrom<f64>`
8#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug)]
9pub enum Sign
10{
11 /// Negative, is a negative [-inf..0)
12 Negative = -1,
13 /// Positive, is not a negative [0..+inf]
14 Positive = 1
15}
16
17impl Sign
18{
19 pub fn to_string_specific<'a>(&self, if_negative: &'a str, if_positive: &'a str) -> &'a str
20 {
21  match self
22  {
23   Sign::Negative => if_negative,
24   Sign::Positive => if_positive
25  }
26 }
27
28 pub fn is_positive(&self) -> bool
29 {
30  match self
31  {
32   Sign::Negative => false,
33   Sign::Positive => true
34  }
35 }
36
37 pub fn is_negative(&self) -> bool
38 {
39  match self
40  {
41   Sign::Negative => true,
42   Sign::Positive => false
43  }
44 }
45
46 pub fn as_f32(&self) -> f32
47 {
48  match self
49  {
50   Sign::Negative => -1f32,
51   _ => 1f32
52  }
53 }
54
55 pub fn as_f64(&self) -> f64
56 {
57  match self
58  {
59   Sign::Negative => -1f64,
60   _ => 1f64
61  }
62 }
63
64 pub fn as_i8(&self) -> i8
65 {
66  match self
67  {
68   Sign::Negative => -1,
69   _ => 1
70  }
71 }
72
73 pub fn as_i16(&self) -> i16
74 {
75  match self
76  {
77   Sign::Negative => -1,
78   _ => 1
79  }
80 }
81
82 pub fn as_i32(&self) -> i32
83 {
84  match self
85  {
86   Sign::Negative => -1,
87   _ => 1
88  }
89 }
90
91 pub fn as_i64(&self) -> i64
92 {
93  match self
94  {
95   Sign::Negative => -1,
96   _ => 1
97  }
98 }
99
100 pub fn as_i128(&self) -> i128
101 {
102  match self
103  {
104   Sign::Negative => -1,
105   _ => 1
106  }
107 }
108
109 pub fn as_u8(&self) -> Result<u8, ArithmeticSignError>
110 {
111  match self
112  {
113   Sign::Negative => Err(ArithmeticSignError::Negative),
114   _ => Ok(1)
115  }
116 }
117
118 pub fn as_u16(&self) -> Result<u16, ArithmeticSignError>
119 {
120  match self
121  {
122   Sign::Negative => Err(ArithmeticSignError::Negative),
123   _ => Ok(1)
124  }
125 }
126
127 pub fn as_u32(&self) -> Result<u32, ArithmeticSignError>
128 {
129  match self
130  {
131   Sign::Negative => Err(ArithmeticSignError::Negative),
132   _ => Ok(1)
133  }
134 }
135
136 pub fn as_u64(&self) -> Result<u64, ArithmeticSignError>
137 {
138  match self
139  {
140   Sign::Negative => Err(ArithmeticSignError::Negative),
141   _ => Ok(1)
142  }
143 }
144
145 pub fn as_u128(&self) -> Result<u128, ArithmeticSignError>
146 {
147  match self
148  {
149   Sign::Negative => Err(ArithmeticSignError::Negative),
150   _ => Ok(1)
151  }
152 }
153}
154
155impl TryFrom<f32> for Sign
156{
157 type Error = ArithmeticSignError;
158
159 fn try_from(v: f32) -> Result<Self, Self::Error>
160 {
161  match v
162  {
163   v if v.is_nan() => Err(ArithmeticSignError::Nan),
164   v if v < 0.0f32 => Ok(Sign::Negative),
165   _ => Ok(Sign::Positive)
166  }
167 }
168}
169
170impl TryFrom<f64> for Sign
171{
172 type Error = ArithmeticSignError;
173
174 fn try_from(v: f64) -> Result<Self, Self::Error>
175 {
176  match v
177  {
178   v if v.is_nan() => Err(ArithmeticSignError::Nan),
179   v if v < 0.0f64 => Ok(Sign::Negative),
180   _ => Ok(Sign::Positive)
181  }
182 }
183}
184
185impl From<i8> for Sign
186{
187 fn from(v: i8) -> Self
188 {
189  if v < 0i8
190  {
191   Sign::Negative
192  }
193  else
194  {
195   Sign::Positive
196  }
197 }
198}
199
200impl From<i16> for Sign
201{
202 fn from(v: i16) -> Self
203 {
204  if v < 0i16
205  {
206   Sign::Negative
207  }
208  else
209  {
210   Sign::Positive
211  }
212 }
213}
214
215impl From<i32> for Sign
216{
217 fn from(v: i32) -> Self
218 {
219  if v < 0i32
220  {
221   Sign::Negative
222  }
223  else
224  {
225   Sign::Positive
226  }
227 }
228}
229
230impl From<i64> for Sign
231{
232 fn from(v: i64) -> Self
233 {
234  if v < 0i64
235  {
236   Sign::Negative
237  }
238  else
239  {
240   Sign::Positive
241  }
242 }
243}
244
245impl From<i128> for Sign
246{
247 fn from(v: i128) -> Self
248 {
249  if v < 0i128
250  {
251   Sign::Negative
252  }
253  else
254  {
255   Sign::Positive
256  }
257 }
258}
259
260impl From<u8> for Sign
261{
262 fn from(_: u8) -> Self
263 {
264  Sign::Positive
265 }
266}
267
268impl From<u16> for Sign
269{
270 fn from(_: u16) -> Self
271 {
272  Sign::Positive
273 }
274}
275
276impl From<u32> for Sign
277{
278 fn from(_: u32) -> Self
279 {
280  Sign::Positive
281 }
282}
283
284impl From<u64> for Sign
285{
286 fn from(_: u64) -> Self
287 {
288  Sign::Positive
289 }
290}
291
292impl From<u128> for Sign
293{
294 fn from(_: u128) -> Self
295 {
296  Sign::Positive
297 }
298}
299
300impl std::ops::Mul for Sign
301{
302 type Output = Sign;
303
304 fn mul(self, rhs: Self) -> Self::Output
305 {
306  match self
307  {
308   Sign::Positive => rhs,
309   Sign::Negative =>
310   {
311    match rhs
312    {
313     Sign::Positive => Sign::Negative,
314     Sign::Negative => Sign::Positive
315    }
316   },
317  }
318 }
319}
320
321impl std::ops::Div for Sign
322{
323 type Output = Sign;
324
325 fn div(self, rhs: Self) -> Self::Output
326 {
327  self * rhs
328 }
329}
330
331impl std::ops::Neg for Sign
332{
333 type Output = Sign;
334
335 fn neg(self) -> Self::Output
336 {
337  match self
338  {
339   Sign::Positive => Sign::Negative,
340   Sign::Negative => Sign::Positive
341  }
342 }
343}
344
345impl std::ops::Not for Sign
346{
347 type Output = Sign;
348
349 fn not(self) -> Self::Output
350 {
351  -self
352 }
353}
354
355impl std::fmt::Display for Sign
356{
357 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
358 {
359  use Sign::*;
360  match self
361  {
362   Negative => write!(f, "-"),
363   Positive => write!(f, "+")
364  }
365 }
366}