1use core::ops::{Add, Div, Mul, Sub};
2
3#[derive(Copy, Clone, PartialEq, Debug)]
4#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5#[cfg_attr(all(feature = "serde", feature = "serde_kebab_case"), serde(rename_all = "kebab-case"))]
6#[cfg_attr(all(feature = "serde", feature = "serde_camel_case"), serde(rename_all = "camelCase"))]
7pub enum Number {
8 Defined(f32),
9 Undefined,
10}
11
12pub trait OrElse<T> {
13 fn or_else(self, other: T) -> T;
14}
15
16impl Default for Number {
17 fn default() -> Self {
18 Self::Undefined
19 }
20}
21
22impl OrElse<f32> for Number {
23 fn or_else(self, other: f32) -> f32 {
24 match self {
25 Number::Defined(val) => val,
26 Number::Undefined => other,
27 }
28 }
29}
30
31impl OrElse<Self> for Number {
32 fn or_else(self, other: Self) -> Self {
33 match self {
34 Number::Defined(_) => self,
35 Number::Undefined => other,
36 }
37 }
38}
39
40impl Number {
41 pub fn is_defined(self) -> bool {
42 match self {
43 Number::Defined(_) => true,
44 Number::Undefined => false,
45 }
46 }
47
48 pub fn is_undefined(self) -> bool {
49 match self {
50 Number::Defined(_) => false,
51 Number::Undefined => true,
52 }
53 }
54}
55
56pub trait MinMax<In, Out> {
57 fn maybe_min(self, rhs: In) -> Out;
58 fn maybe_max(self, rhs: In) -> Out;
59}
60
61impl MinMax<Self, Self> for Number {
62 fn maybe_min(self, rhs: Self) -> Self {
63 match (self, rhs) {
64 (Number::Defined(l), Number::Defined(r)) => Number::Defined(l.min(r)),
65 (Number::Defined(_), _) => self,
66 _ => Number::Undefined,
67 }
68 }
69
70 fn maybe_max(self, rhs: Self) -> Self {
71 match (self, rhs) {
72 (Number::Defined(l), Number::Defined(r)) => Number::Defined(l.max(r)),
73 (Number::Defined(_), _) => self,
74 _ => Number::Undefined,
75 }
76 }
77}
78
79impl MinMax<f32, Number> for Number {
80 fn maybe_min(self, rhs: f32) -> Self {
81 match self {
82 Number::Defined(val) => Number::Defined(val.min(rhs)),
83 Number::Undefined => Number::Undefined,
84 }
85 }
86
87 fn maybe_max(self, rhs: f32) -> Self {
88 match self {
89 Number::Defined(val) => Number::Defined(val.max(rhs)),
90 Number::Undefined => Number::Undefined,
91 }
92 }
93}
94
95impl MinMax<Number, f32> for f32 {
96 fn maybe_min(self, rhs: Number) -> f32 {
97 match rhs {
98 Number::Defined(val) => self.min(val),
99 Number::Undefined => self,
100 }
101 }
102
103 fn maybe_max(self, rhs: Number) -> f32 {
104 match rhs {
105 Number::Defined(val) => self.max(val),
106 Number::Undefined => self,
107 }
108 }
109}
110
111impl From<f32> for Number {
112 fn from(v: f32) -> Self {
113 Self::Defined(v)
114 }
115}
116
117impl Add<f32> for Number {
118 type Output = Number;
119
120 fn add(self, rhs: f32) -> Self {
121 match self {
122 Number::Defined(val) => Number::Defined(val + rhs),
123 Number::Undefined => Number::Undefined,
124 }
125 }
126}
127
128impl Add<Number> for Number {
129 type Output = Number;
130
131 fn add(self, rhs: Self) -> Self {
132 match (self, rhs) {
133 (Number::Defined(l), Number::Defined(r)) => Number::Defined(l + r),
134 (Number::Defined(_), _) => self,
135 _ => Number::Undefined,
136 }
137 }
138}
139
140impl Sub<f32> for Number {
141 type Output = Number;
142
143 fn sub(self, rhs: f32) -> Self {
144 match self {
145 Number::Defined(val) => Number::Defined(val - rhs),
146 Number::Undefined => Number::Undefined,
147 }
148 }
149}
150
151impl Sub<Number> for Number {
152 type Output = Number;
153
154 fn sub(self, rhs: Self) -> Self {
155 match (self, rhs) {
156 (Number::Defined(l), Number::Defined(r)) => Number::Defined(l - r),
157 (Number::Defined(_), _) => self,
158 _ => Number::Undefined,
159 }
160 }
161}
162
163impl Mul<f32> for Number {
164 type Output = Number;
165
166 fn mul(self, rhs: f32) -> Self {
167 match self {
168 Number::Defined(val) => Number::Defined(val * rhs),
169 Number::Undefined => Number::Undefined,
170 }
171 }
172}
173
174impl Mul<Number> for Number {
175 type Output = Number;
176
177 fn mul(self, rhs: Self) -> Self {
178 match (self, rhs) {
179 (Number::Defined(l), Number::Defined(r)) => Number::Defined(l * r),
180 (Number::Defined(_), _) => self,
181 _ => Number::Undefined,
182 }
183 }
184}
185
186impl Div<f32> for Number {
187 type Output = Number;
188
189 fn div(self, rhs: f32) -> Self {
190 match self {
191 Number::Defined(val) => Number::Defined(val / rhs),
192 Number::Undefined => Number::Undefined,
193 }
194 }
195}
196
197impl Div<Number> for Number {
198 type Output = Number;
199
200 fn div(self, rhs: Self) -> Self {
201 match (self, rhs) {
202 (Number::Defined(l), Number::Defined(r)) => Number::Defined(l / r),
203 (Number::Defined(_), _) => self,
204 _ => Number::Undefined,
205 }
206 }
207}