elasticsearch_dsl/search/params/
number.rs1use std::cmp::Ordering;
2
3#[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd)]
5pub struct Number(N);
6
7#[derive(Clone, Copy, Serialize, Deserialize)]
8#[serde(untagged)]
9enum N {
10 Pos(u64),
12
13 Neg(i64),
15
16 F32(f32),
18
19 F64(f64),
21}
22
23impl std::fmt::Debug for Number {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 match self.0 {
26 N::Pos(value) => value.fmt(f),
27 N::Neg(value) => value.fmt(f),
28 N::F32(value) => value.fmt(f),
29 N::F64(value) => value.fmt(f),
30 }
31 }
32}
33
34impl std::fmt::Display for Number {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 match self.0 {
37 N::Pos(value) => value.fmt(f),
38 N::Neg(value) => value.fmt(f),
39 N::F32(value) => value.fmt(f),
40 N::F64(value) => value.fmt(f),
41 }
42 }
43}
44
45impl From<u8> for Number {
46 fn from(value: u8) -> Self {
47 Self(N::Pos(value as u64))
48 }
49}
50
51impl From<u16> for Number {
52 fn from(value: u16) -> Self {
53 Self(N::Pos(value as u64))
54 }
55}
56
57impl From<u32> for Number {
58 fn from(value: u32) -> Self {
59 Self(N::Pos(value as u64))
60 }
61}
62
63impl From<u64> for Number {
64 fn from(value: u64) -> Self {
65 Self(N::Pos(value))
66 }
67}
68
69impl From<i8> for Number {
70 fn from(value: i8) -> Self {
71 if value < 0 {
72 Self(N::Neg(value as i64))
73 } else {
74 Self(N::Pos(value as u64))
75 }
76 }
77}
78
79impl From<i16> for Number {
80 fn from(value: i16) -> Self {
81 if value < 0 {
82 Self(N::Neg(value as i64))
83 } else {
84 Self(N::Pos(value as u64))
85 }
86 }
87}
88
89impl From<i32> for Number {
90 fn from(value: i32) -> Self {
91 if value < 0 {
92 Self(N::Neg(value as i64))
93 } else {
94 Self(N::Pos(value as u64))
95 }
96 }
97}
98
99impl From<i64> for Number {
100 fn from(value: i64) -> Self {
101 if value < 0 {
102 Self(N::Neg(value))
103 } else {
104 Self(N::Pos(value as u64))
105 }
106 }
107}
108
109impl From<f32> for Number {
110 fn from(value: f32) -> Self {
111 Self(N::F32(value))
112 }
113}
114
115impl From<f64> for Number {
116 fn from(value: f64) -> Self {
117 Self(N::F64(value))
118 }
119}
120
121impl From<&u8> for Number {
122 fn from(value: &u8) -> Self {
123 Self(N::Pos(*value as u64))
124 }
125}
126
127impl From<&u16> for Number {
128 fn from(value: &u16) -> Self {
129 Self(N::Pos(*value as u64))
130 }
131}
132
133impl From<&u32> for Number {
134 fn from(value: &u32) -> Self {
135 Self(N::Pos(*value as u64))
136 }
137}
138
139impl From<&u64> for Number {
140 fn from(value: &u64) -> Self {
141 Self(N::Pos(*value))
142 }
143}
144
145impl From<&i8> for Number {
146 fn from(value: &i8) -> Self {
147 let value = *value;
148 if value < 0 {
149 Self(N::Neg(value as i64))
150 } else {
151 Self(N::Pos(value as u64))
152 }
153 }
154}
155
156impl From<&i16> for Number {
157 fn from(value: &i16) -> Self {
158 let value = *value;
159 if value < 0 {
160 Self(N::Neg(value as i64))
161 } else {
162 Self(N::Pos(value as u64))
163 }
164 }
165}
166
167impl From<&i32> for Number {
168 fn from(value: &i32) -> Self {
169 let value = *value;
170 if value < 0 {
171 Self(N::Neg(value as i64))
172 } else {
173 Self(N::Pos(value as u64))
174 }
175 }
176}
177
178impl From<&i64> for Number {
179 fn from(value: &i64) -> Self {
180 let value = *value;
181 if value < 0 {
182 Self(N::Neg(value))
183 } else {
184 Self(N::Pos(value as u64))
185 }
186 }
187}
188
189impl From<&f32> for Number {
190 fn from(value: &f32) -> Self {
191 Self(N::F32(*value))
192 }
193}
194
195impl From<&f64> for Number {
196 fn from(value: &f64) -> Self {
197 Self(N::F64(*value))
198 }
199}
200
201impl PartialEq for N {
202 fn eq(&self, other: &Self) -> bool {
203 match (self, other) {
204 (N::Pos(value), N::Pos(other)) => value.eq(other),
206 (N::Pos(_), N::Neg(_)) => false,
207 (N::Pos(value), N::F32(other)) => (*value as f32).eq(other),
208 (N::Pos(value), N::F64(other)) => (*value as f64).eq(other),
209
210 (N::Neg(_), N::Pos(_)) => false,
212 (N::Neg(value), N::Neg(other)) => value.eq(other),
213 (N::Neg(value), N::F32(other)) => (*value as f32).eq(other),
214 (N::Neg(value), N::F64(other)) => (*value as f64).eq(other),
215
216 (N::F32(value), N::Pos(other)) => value.eq(&(*other as f32)),
218 (N::F32(value), N::Neg(other)) => value.eq(&(*other as f32)),
219 (N::F32(value), N::F32(other)) => value.eq(other),
220 (N::F32(value), N::F64(other)) => value.eq(&(*other as f32)),
221
222 (N::F64(value), N::Pos(other)) => value.eq(&(*other as f64)),
224 (N::F64(value), N::Neg(other)) => value.eq(&(*other as f64)),
225 (N::F64(value), N::F32(other)) => (*value as f32).eq(other),
226 (N::F64(value), N::F64(other)) => value.eq(other),
227 }
228 }
229}
230
231impl Eq for N {}
232
233impl PartialOrd for N {
234 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
235 match (self, other) {
236 (N::Pos(value), N::Pos(other)) => value.partial_cmp(other),
238 (N::Pos(_), N::Neg(_)) => Some(Ordering::Greater),
239 (N::Pos(value), N::F32(other)) => (*value as f32).partial_cmp(other),
240 (N::Pos(value), N::F64(other)) => (*value as f64).partial_cmp(other),
241
242 (N::Neg(_), N::Pos(_)) => Some(Ordering::Less),
244 (N::Neg(value), N::Neg(other)) => value.partial_cmp(other),
245 (N::Neg(value), N::F32(other)) => (*value as f32).partial_cmp(other),
246 (N::Neg(value), N::F64(other)) => (*value as f64).partial_cmp(other),
247
248 (N::F32(value), N::Pos(other)) => value.partial_cmp(&(*other as f32)),
250 (N::F32(value), N::Neg(other)) => value.partial_cmp(&(*other as f32)),
251 (N::F32(value), N::F32(other)) => value.partial_cmp(other),
252 (N::F32(value), N::F64(other)) => value.partial_cmp(&(*other as f32)),
253
254 (N::F64(value), N::Pos(other)) => value.partial_cmp(&(*other as f64)),
256 (N::F64(value), N::Neg(other)) => value.partial_cmp(&(*other as f64)),
257 (N::F64(value), N::F32(other)) => (*value as f32).partial_cmp(other),
258 (N::F64(value), N::F64(other)) => value.partial_cmp(other),
259 }
260 }
261}
262
263#[cfg(test)]
264mod tests {
265 use super::*;
266 use crate::util::*;
267
268 #[test]
269 fn serialization() {
270 assert_serialize(
271 [
272 Number::from(2),
273 Number::from(-2),
274 Number::from(2.2f32),
275 Number::from(2.2f64),
276 ],
277 json!([2, -2, 2.2, 2.2]),
278 )
279 }
280
281 #[test]
282 fn partial_eq() {
283 assert_eq!(Number::from(2f32), Number::from(2));
284 assert_eq!(Number::from(2f64), Number::from(2));
285 assert_eq!(Number::from(2), Number::from(2));
286 assert_eq!(Number::from(-2), Number::from(-2));
287 }
288
289 #[test]
290 fn partial_ord() {
291 assert!(Number::from(2) > Number::from(1));
292 assert!(Number::from(2) > Number::from(-1));
293 assert!(Number::from(2) > Number::from(1f32));
294 assert!(Number::from(2) > Number::from(1f64));
295
296 assert!(Number::from(-2) < Number::from(1));
297 assert!(Number::from(-2) < Number::from(-1));
298 assert!(Number::from(-2) < Number::from(1f32));
299 assert!(Number::from(-2) < Number::from(1f64));
300
301 assert!(Number::from(2f32) > Number::from(1));
302 assert!(Number::from(2f32) > Number::from(-1));
303 assert!(Number::from(2f32) > Number::from(1f32));
304 assert!(Number::from(2f32) > Number::from(1f64));
305
306 assert!(Number::from(2f64) > Number::from(1));
307 assert!(Number::from(2f64) > Number::from(-1));
308 assert!(Number::from(2f64) > Number::from(1f32));
309 assert!(Number::from(2f64) > Number::from(1f64));
310 }
311}