devela/num/
sign.rs
1use crate::{
11 ConstDefault,
12 NumError::{self, Invalid},
13 NumResult as Result,
14};
15
16#[must_use]
18#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
19pub enum Sign {
20 Negative = -1,
22
23 #[default]
25 None = 0,
26
27 Positive = 1,
29}
30
31impl ConstDefault for Sign {
32 const DEFAULT: Self = Sign::None;
34}
35
36macro_rules! impl_into_sign {
40 (int: $($int:ty),+) => { $( impl_into_sign![@int: $int]; )+ };
42 (@int: $int:ty) => {
43 impl From<$int> for Sign {
44 fn from(n: $int) -> Sign {
46 match n {
47 0 => Sign::None,
48 1.. => Sign::Positive,
49 #[allow(unreachable_patterns, reason = "for unsigned")]
50 _ => Sign::Negative,
51 }
52 }
53 }
54 };
55 (float: $($float:ty),+) => { $( impl_into_sign![@float: $float]; )+ };
57 (@float: $float:ty) => {
58 impl From<$float> for Sign {
59 fn from(n: $float) -> Sign {
61 if n.is_sign_positive() {
62 Sign::Positive
63 } else {
64 Sign::Negative
65 }
66 }
67 }
68 };
69 (bool) => {
71 impl From<bool> for Sign {
72 fn from(n: bool) -> Sign {
74 match n {
75 true => Sign::Positive,
76 false => Sign::Negative,
77 }
78 }
79 }
80 };
81}
82impl_into_sign![int: u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize];
83impl_into_sign![float: f32, f64];
84impl_into_sign![bool];
85
86macro_rules! impl_from_sign {
90 (sint: $($sint:ty),+) => { $( impl_from_sign![@sint: $sint]; )+ };
92 (@sint: $sint:ty) => {
93 impl From<Sign> for $sint {
94 fn from(s: Sign) -> $sint {
96 match s {
97 Sign::None => 0,
98 Sign::Positive => 1,
99 Sign::Negative => -1,
100 }
101 }
102 }
103 };
104 (uint: $($uint:ty),+) => { $( impl_from_sign![@uint: $uint]; )+ };
106 (@uint: $uint:ty) => {
107 impl TryFrom<Sign> for $uint {
108 type Error = NumError;
109
110 fn try_from(s: Sign) -> Result<$uint> {
115 match s {
116 Sign::None => Ok(0),
117 Sign::Positive => Ok(1),
118 Sign::Negative => Err(Invalid),
119 }
120 }
121 }
122 };
123 (float: $($float:ty),+) => { $( impl_from_sign![@float: $float]; )+ };
125 (@float: $float:ty) => {
126 impl From<Sign> for $float {
127 fn from(s: Sign) -> $float {
129 match s {
130 Sign::None => 0.0,
131 Sign::Positive => 1.0,
132 Sign::Negative => -1.0,
133 }
134 }
135 }
136 };
137 (bool) => {
139 impl TryFrom<Sign> for bool {
140 type Error = NumError;
141
142 fn try_from(s: Sign) -> Result<bool> {
147 match s {
148 Sign::Positive => Ok(true),
149 Sign::Negative => Ok(false),
150 Sign::None => Err(Invalid),
151 }
152 }
153 }
154 };
155}
156impl_from_sign![sint: i8, i16, i32, i64, i128, isize];
157impl_from_sign![uint: u8, u16, u32, u64, u128, usize];
158impl_from_sign![float: f32, f64];
159impl_from_sign![bool];