surrealdb_sql/
number.rs

1use super::value::{TryAdd, TryDiv, TryMul, TryNeg, TryPow, TrySub};
2use crate::err::Error;
3use crate::strand::Strand;
4use revision::revisioned;
5use rust_decimal::prelude::*;
6use serde::{Deserialize, Serialize};
7use std::cmp::Ordering;
8use std::fmt::{self, Display, Formatter};
9use std::hash;
10use std::iter::Product;
11use std::iter::Sum;
12use std::ops::{self, Add, Div, Mul, Neg, Sub};
13use std::str::FromStr;
14
15pub(crate) const TOKEN: &str = "$surrealdb::private::crate::Number";
16
17#[derive(Clone, Debug, Serialize, Deserialize)]
18#[serde(rename = "$surrealdb::private::crate::Number")]
19#[revisioned(revision = 1)]
20pub enum Number {
21	Int(i64),
22	Float(f64),
23	Decimal(Decimal),
24	// Add new variants here
25}
26
27impl Default for Number {
28	fn default() -> Self {
29		Self::Int(0)
30	}
31}
32
33macro_rules! from_prim_ints {
34	($($int: ty),*) => {
35		$(
36			impl From<$int> for Number {
37				fn from(i: $int) -> Self {
38					Self::Int(i as i64)
39				}
40			}
41		)*
42	};
43}
44
45from_prim_ints!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
46
47impl From<f32> for Number {
48	fn from(f: f32) -> Self {
49		Self::Float(f as f64)
50	}
51}
52
53impl From<f64> for Number {
54	fn from(f: f64) -> Self {
55		Self::Float(f)
56	}
57}
58
59impl From<Decimal> for Number {
60	fn from(v: Decimal) -> Self {
61		Self::Decimal(v)
62	}
63}
64
65impl FromStr for Number {
66	type Err = ();
67	fn from_str(s: &str) -> Result<Self, Self::Err> {
68		Self::try_from(s)
69	}
70}
71
72impl TryFrom<String> for Number {
73	type Error = ();
74	fn try_from(v: String) -> Result<Self, Self::Error> {
75		Self::try_from(v.as_str())
76	}
77}
78
79impl TryFrom<Strand> for Number {
80	type Error = ();
81	fn try_from(v: Strand) -> Result<Self, Self::Error> {
82		Self::try_from(v.as_str())
83	}
84}
85
86impl TryFrom<&str> for Number {
87	type Error = ();
88	fn try_from(v: &str) -> Result<Self, Self::Error> {
89		// Attempt to parse as i64
90		match v.parse::<i64>() {
91			// Store it as an i64
92			Ok(v) => Ok(Self::Int(v)),
93			// It wasn't parsed as a i64 so parse as a float
94			_ => match f64::from_str(v) {
95				// Store it as a float
96				Ok(v) => Ok(Self::Float(v)),
97				// It wasn't parsed as a number
98				_ => Err(()),
99			},
100		}
101	}
102}
103
104macro_rules! try_into_prim {
105	// TODO: switch to one argument per int once https://github.com/rust-lang/rust/issues/29599 is stable
106	($($int: ty => $to_int: ident),*) => {
107		$(
108			impl TryFrom<Number> for $int {
109				type Error = Error;
110				fn try_from(value: Number) -> Result<Self, Self::Error> {
111					match value {
112						Number::Int(v) => match v.$to_int() {
113							Some(v) => Ok(v),
114							None => Err(Error::TryFrom(value.to_string(), stringify!($int))),
115						},
116						Number::Float(v) => match v.$to_int() {
117							Some(v) => Ok(v),
118							None => Err(Error::TryFrom(value.to_string(), stringify!($int))),
119						},
120						Number::Decimal(ref v) => match v.$to_int() {
121							Some(v) => Ok(v),
122							None => Err(Error::TryFrom(value.to_string(), stringify!($int))),
123						},
124					}
125				}
126			}
127		)*
128	};
129}
130
131try_into_prim!(
132	i8 => to_i8, i16 => to_i16, i32 => to_i32, i64 => to_i64, i128 => to_i128,
133	u8 => to_u8, u16 => to_u16, u32 => to_u32, u64 => to_u64, u128 => to_u128,
134	f32 => to_f32, f64 => to_f64
135);
136
137impl TryFrom<Number> for Decimal {
138	type Error = Error;
139	fn try_from(value: Number) -> Result<Self, Self::Error> {
140		match value {
141			Number::Int(v) => match Decimal::from_i64(v) {
142				Some(v) => Ok(v),
143				None => Err(Error::TryFrom(value.to_string(), "Decimal")),
144			},
145			Number::Float(v) => match Decimal::try_from(v) {
146				Ok(v) => Ok(v),
147				_ => Err(Error::TryFrom(value.to_string(), "Decimal")),
148			},
149			Number::Decimal(x) => Ok(x),
150		}
151	}
152}
153
154impl Display for Number {
155	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
156		match self {
157			Number::Int(v) => Display::fmt(v, f),
158			Number::Float(v) => {
159				if v.is_finite() {
160					// Add suffix to distinguish between int and float
161					write!(f, "{v}f")
162				} else {
163					// Don't add suffix for NaN, inf, -inf
164					Display::fmt(v, f)
165				}
166			}
167			Number::Decimal(v) => write!(f, "{v}dec"),
168		}
169	}
170}
171
172impl Number {
173	// -----------------------------------
174	// Constants
175	// -----------------------------------
176
177	pub const NAN: Number = Number::Float(f64::NAN);
178
179	// -----------------------------------
180	// Simple number detection
181	// -----------------------------------
182
183	pub fn is_nan(&self) -> bool {
184		matches!(self, Number::Float(v) if v.is_nan())
185	}
186
187	pub fn is_int(&self) -> bool {
188		matches!(self, Number::Int(_))
189	}
190
191	pub fn is_float(&self) -> bool {
192		matches!(self, Number::Float(_))
193	}
194
195	pub fn is_decimal(&self) -> bool {
196		matches!(self, Number::Decimal(_))
197	}
198
199	pub fn is_integer(&self) -> bool {
200		match self {
201			Number::Int(_) => true,
202			Number::Float(v) => v.fract() == 0.0,
203			Number::Decimal(v) => v.is_integer(),
204		}
205	}
206
207	pub fn is_truthy(&self) -> bool {
208		match self {
209			Number::Int(v) => v != &0,
210			Number::Float(v) => v != &0.0,
211			Number::Decimal(v) => v != &Decimal::ZERO,
212		}
213	}
214
215	pub fn is_positive(&self) -> bool {
216		match self {
217			Number::Int(v) => v > &0,
218			Number::Float(v) => v > &0.0,
219			Number::Decimal(v) => v > &Decimal::ZERO,
220		}
221	}
222
223	pub fn is_negative(&self) -> bool {
224		match self {
225			Number::Int(v) => v < &0,
226			Number::Float(v) => v < &0.0,
227			Number::Decimal(v) => v < &Decimal::ZERO,
228		}
229	}
230
231	pub fn is_zero(&self) -> bool {
232		match self {
233			Number::Int(v) => v == &0,
234			Number::Float(v) => v == &0.0,
235			Number::Decimal(v) => v == &Decimal::ZERO,
236		}
237	}
238
239	pub fn is_zero_or_positive(&self) -> bool {
240		match self {
241			Number::Int(v) => v >= &0,
242			Number::Float(v) => v >= &0.0,
243			Number::Decimal(v) => v >= &Decimal::ZERO,
244		}
245	}
246
247	pub fn is_zero_or_negative(&self) -> bool {
248		match self {
249			Number::Int(v) => v <= &0,
250			Number::Float(v) => v <= &0.0,
251			Number::Decimal(v) => v <= &Decimal::ZERO,
252		}
253	}
254
255	// -----------------------------------
256	// Simple conversion of number
257	// -----------------------------------
258
259	pub fn as_usize(self) -> usize {
260		match self {
261			Number::Int(v) => v as usize,
262			Number::Float(v) => v as usize,
263			Number::Decimal(v) => v.try_into().unwrap_or_default(),
264		}
265	}
266
267	pub fn as_int(self) -> i64 {
268		match self {
269			Number::Int(v) => v,
270			Number::Float(v) => v as i64,
271			Number::Decimal(v) => v.try_into().unwrap_or_default(),
272		}
273	}
274
275	pub fn as_float(self) -> f64 {
276		match self {
277			Number::Int(v) => v as f64,
278			Number::Float(v) => v,
279			Number::Decimal(v) => v.try_into().unwrap_or_default(),
280		}
281	}
282
283	pub fn as_decimal(self) -> Decimal {
284		match self {
285			Number::Int(v) => Decimal::from(v),
286			Number::Float(v) => Decimal::try_from(v).unwrap_or_default(),
287			Number::Decimal(v) => v,
288		}
289	}
290
291	// -----------------------------------
292	// Complex conversion of number
293	// -----------------------------------
294
295	pub fn to_usize(&self) -> usize {
296		match self {
297			Number::Int(v) => *v as usize,
298			Number::Float(v) => *v as usize,
299			Number::Decimal(v) => v.to_usize().unwrap_or_default(),
300		}
301	}
302
303	pub fn to_int(&self) -> i64 {
304		match self {
305			Number::Int(v) => *v,
306			Number::Float(v) => *v as i64,
307			Number::Decimal(v) => v.to_i64().unwrap_or_default(),
308		}
309	}
310
311	pub fn to_float(&self) -> f64 {
312		match self {
313			Number::Int(v) => *v as f64,
314			Number::Float(v) => *v,
315			&Number::Decimal(v) => v.try_into().unwrap_or_default(),
316		}
317	}
318
319	pub fn to_decimal(&self) -> Decimal {
320		match self {
321			// #[allow(clippy::unnecessary_fallible_conversions)] // `Decimal::from` can panic
322			// `clippy::unnecessary_fallible_conversions` not available on Rust < v1.75
323			#[allow(warnings)]
324			Number::Int(v) => Decimal::try_from(*v).unwrap_or_default(),
325			Number::Float(v) => Decimal::try_from(*v).unwrap_or_default(),
326			Number::Decimal(v) => *v,
327		}
328	}
329
330	// -----------------------------------
331	//
332	// -----------------------------------
333
334	pub fn abs(self) -> Self {
335		match self {
336			Number::Int(v) => v.abs().into(),
337			Number::Float(v) => v.abs().into(),
338			Number::Decimal(v) => v.abs().into(),
339		}
340	}
341
342	pub fn acos(self) -> Self {
343		self.to_float().acos().into()
344	}
345
346	pub fn ceil(self) -> Self {
347		match self {
348			Number::Int(v) => v.into(),
349			Number::Float(v) => v.ceil().into(),
350			Number::Decimal(v) => v.ceil().into(),
351		}
352	}
353
354	pub fn floor(self) -> Self {
355		match self {
356			Number::Int(v) => v.into(),
357			Number::Float(v) => v.floor().into(),
358			Number::Decimal(v) => v.floor().into(),
359		}
360	}
361
362	pub fn round(self) -> Self {
363		match self {
364			Number::Int(v) => v.into(),
365			Number::Float(v) => v.round().into(),
366			Number::Decimal(v) => v.round().into(),
367		}
368	}
369
370	pub fn fixed(self, precision: usize) -> Number {
371		match self {
372			Number::Int(v) => format!("{v:.precision$}").try_into().unwrap_or_default(),
373			Number::Float(v) => format!("{v:.precision$}").try_into().unwrap_or_default(),
374			Number::Decimal(v) => v.round_dp(precision as u32).into(),
375		}
376	}
377
378	pub fn sqrt(self) -> Self {
379		match self {
380			Number::Int(v) => (v as f64).sqrt().into(),
381			Number::Float(v) => v.sqrt().into(),
382			Number::Decimal(v) => v.sqrt().unwrap_or_default().into(),
383		}
384	}
385
386	pub fn pow(self, power: Number) -> Number {
387		match (self, power) {
388			(Number::Int(v), Number::Int(p)) => Number::Int(v.pow(p as u32)),
389			(Number::Decimal(v), Number::Int(p)) => v.powi(p).into(),
390			// TODO: (Number::Decimal(v), Number::Float(p)) => todo!(),
391			// TODO: (Number::Decimal(v), Number::Decimal(p)) => todo!(),
392			(v, p) => v.as_float().powf(p.as_float()).into(),
393		}
394	}
395}
396
397impl Eq for Number {}
398
399impl Ord for Number {
400	fn cmp(&self, other: &Self) -> Ordering {
401		fn total_cmp_f64(a: f64, b: f64) -> Ordering {
402			if a == 0.0 && b == 0.0 {
403				// -0.0 = 0.0
404				Ordering::Equal
405			} else {
406				// Handles NaN's
407				a.total_cmp(&b)
408			}
409		}
410
411		match (self, other) {
412			(Number::Int(v), Number::Int(w)) => v.cmp(w),
413			(Number::Float(v), Number::Float(w)) => total_cmp_f64(*v, *w),
414			(Number::Decimal(v), Number::Decimal(w)) => v.cmp(w),
415			// ------------------------------
416			(Number::Int(v), Number::Float(w)) => total_cmp_f64(*v as f64, *w),
417			(Number::Float(v), Number::Int(w)) => total_cmp_f64(*v, *w as f64),
418			// ------------------------------
419			(Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).cmp(w),
420			(Number::Decimal(v), Number::Int(w)) => v.cmp(&Decimal::from(*w)),
421			// ------------------------------
422			(Number::Float(v), Number::Decimal(w)) => {
423				// `rust_decimal::Decimal` code comments indicate that `to_f64` is infallible
424				total_cmp_f64(*v, w.to_f64().unwrap())
425			}
426			(Number::Decimal(v), Number::Float(w)) => total_cmp_f64(v.to_f64().unwrap(), *w),
427		}
428	}
429}
430
431// Warning: Equal numbers may have different hashes, which violates
432// the invariants of certain collections!
433impl hash::Hash for Number {
434	fn hash<H: hash::Hasher>(&self, state: &mut H) {
435		match self {
436			Number::Int(v) => v.hash(state),
437			Number::Float(v) => v.to_bits().hash(state),
438			Number::Decimal(v) => v.hash(state),
439		}
440	}
441}
442
443impl PartialEq for Number {
444	fn eq(&self, other: &Self) -> bool {
445		fn total_eq_f64(a: f64, b: f64) -> bool {
446			a.to_bits().eq(&b.to_bits()) || (a == 0.0 && b == 0.0)
447		}
448
449		match (self, other) {
450			(Number::Int(v), Number::Int(w)) => v.eq(w),
451			(Number::Float(v), Number::Float(w)) => total_eq_f64(*v, *w),
452			(Number::Decimal(v), Number::Decimal(w)) => v.eq(w),
453			// ------------------------------
454			(Number::Int(v), Number::Float(w)) => total_eq_f64(*v as f64, *w),
455			(Number::Float(v), Number::Int(w)) => total_eq_f64(*v, *w as f64),
456			// ------------------------------
457			(Number::Int(v), Number::Decimal(w)) => Decimal::from(*v).eq(w),
458			(Number::Decimal(v), Number::Int(w)) => v.eq(&Decimal::from(*w)),
459			// ------------------------------
460			(Number::Float(v), Number::Decimal(w)) => total_eq_f64(*v, w.to_f64().unwrap()),
461			(Number::Decimal(v), Number::Float(w)) => total_eq_f64(v.to_f64().unwrap(), *w),
462		}
463	}
464}
465
466impl PartialOrd for Number {
467	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
468		Some(self.cmp(other))
469	}
470}
471
472macro_rules! impl_simple_try_op {
473	($trt:ident, $fn:ident, $unchecked:ident, $checked:ident) => {
474		impl $trt for Number {
475			type Output = Self;
476			fn $fn(self, other: Self) -> Result<Self, Error> {
477				Ok(match (self, other) {
478					(Number::Int(v), Number::Int(w)) => Number::Int(
479						v.$checked(w).ok_or_else(|| Error::$trt(v.to_string(), w.to_string()))?,
480					),
481					(Number::Float(v), Number::Float(w)) => Number::Float(v.$unchecked(w)),
482					(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(
483						v.$checked(w).ok_or_else(|| Error::$trt(v.to_string(), w.to_string()))?,
484					),
485					(Number::Int(v), Number::Float(w)) => Number::Float((v as f64).$unchecked(w)),
486					(Number::Float(v), Number::Int(w)) => Number::Float(v.$unchecked(w as f64)),
487					(v, w) => Number::Decimal(
488						v.to_decimal()
489							.$checked(w.to_decimal())
490							.ok_or_else(|| Error::$trt(v.to_string(), w.to_string()))?,
491					),
492				})
493			}
494		}
495	};
496}
497
498impl_simple_try_op!(TryAdd, try_add, add, checked_add);
499impl_simple_try_op!(TrySub, try_sub, sub, checked_sub);
500impl_simple_try_op!(TryMul, try_mul, mul, checked_mul);
501impl_simple_try_op!(TryDiv, try_div, div, checked_div);
502
503impl TryPow for Number {
504	type Output = Self;
505	fn try_pow(self, power: Self) -> Result<Self, Error> {
506		Ok(match (self, power) {
507			(Self::Int(v), Self::Int(p)) => Self::Int(match v {
508				0 => match p.cmp(&0) {
509					// 0^(-x)
510					Ordering::Less => return Err(Error::TryPow(v.to_string(), p.to_string())),
511					// 0^0
512					Ordering::Equal => 1,
513					// 0^x
514					Ordering::Greater => 0,
515				},
516				// 1^p
517				1 => 1,
518				-1 => {
519					if p % 2 == 0 {
520						// (-1)^even
521						1
522					} else {
523						// (-1)^odd
524						-1
525					}
526				}
527				// try_into may cause an error, which would be wrong for the above cases.
528				_ => p
529					.try_into()
530					.ok()
531					.and_then(|p| v.checked_pow(p))
532					.ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
533			}),
534			(Self::Decimal(v), Self::Int(p)) => Self::Decimal(
535				v.checked_powi(p).ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
536			),
537			(Self::Decimal(v), Self::Float(p)) => Self::Decimal(
538				v.checked_powf(p).ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
539			),
540			(Self::Decimal(v), Self::Decimal(p)) => Self::Decimal(
541				v.checked_powd(p).ok_or_else(|| Error::TryPow(v.to_string(), p.to_string()))?,
542			),
543			(v, p) => v.as_float().powf(p.as_float()).into(),
544		})
545	}
546}
547
548impl TryNeg for Number {
549	type Output = Self;
550
551	fn try_neg(self) -> Result<Self::Output, Error> {
552		Ok(match self {
553			Self::Int(n) => {
554				Number::Int(n.checked_neg().ok_or_else(|| Error::TryNeg(n.to_string()))?)
555			}
556			Self::Float(n) => Number::Float(-n),
557			Self::Decimal(n) => Number::Decimal(-n),
558		})
559	}
560}
561
562impl ops::Add for Number {
563	type Output = Self;
564	fn add(self, other: Self) -> Self {
565		match (self, other) {
566			(Number::Int(v), Number::Int(w)) => Number::Int(v + w),
567			(Number::Float(v), Number::Float(w)) => Number::Float(v + w),
568			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v + w),
569			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 + w),
570			(Number::Float(v), Number::Int(w)) => Number::Float(v + w as f64),
571			(v, w) => Number::from(v.as_decimal() + w.as_decimal()),
572		}
573	}
574}
575
576impl<'a, 'b> ops::Add<&'b Number> for &'a Number {
577	type Output = Number;
578	fn add(self, other: &'b Number) -> Number {
579		match (self, other) {
580			(Number::Int(v), Number::Int(w)) => Number::Int(v + w),
581			(Number::Float(v), Number::Float(w)) => Number::Float(v + w),
582			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v + w),
583			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 + w),
584			(Number::Float(v), Number::Int(w)) => Number::Float(v + *w as f64),
585			(v, w) => Number::from(v.to_decimal() + w.to_decimal()),
586		}
587	}
588}
589
590impl ops::Sub for Number {
591	type Output = Self;
592	fn sub(self, other: Self) -> Self {
593		match (self, other) {
594			(Number::Int(v), Number::Int(w)) => Number::Int(v - w),
595			(Number::Float(v), Number::Float(w)) => Number::Float(v - w),
596			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v - w),
597			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 - w),
598			(Number::Float(v), Number::Int(w)) => Number::Float(v - w as f64),
599			(v, w) => Number::from(v.as_decimal() - w.as_decimal()),
600		}
601	}
602}
603
604impl<'a, 'b> ops::Sub<&'b Number> for &'a Number {
605	type Output = Number;
606	fn sub(self, other: &'b Number) -> Number {
607		match (self, other) {
608			(Number::Int(v), Number::Int(w)) => Number::Int(v - w),
609			(Number::Float(v), Number::Float(w)) => Number::Float(v - w),
610			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v - w),
611			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 - w),
612			(Number::Float(v), Number::Int(w)) => Number::Float(v - *w as f64),
613			(v, w) => Number::from(v.to_decimal() - w.to_decimal()),
614		}
615	}
616}
617
618impl ops::Mul for Number {
619	type Output = Self;
620	fn mul(self, other: Self) -> Self {
621		match (self, other) {
622			(Number::Int(v), Number::Int(w)) => Number::Int(v * w),
623			(Number::Float(v), Number::Float(w)) => Number::Float(v * w),
624			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v * w),
625			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 * w),
626			(Number::Float(v), Number::Int(w)) => Number::Float(v * w as f64),
627			(v, w) => Number::from(v.as_decimal() * w.as_decimal()),
628		}
629	}
630}
631
632impl<'a, 'b> ops::Mul<&'b Number> for &'a Number {
633	type Output = Number;
634	fn mul(self, other: &'b Number) -> Number {
635		match (self, other) {
636			(Number::Int(v), Number::Int(w)) => Number::Int(v * w),
637			(Number::Float(v), Number::Float(w)) => Number::Float(v * w),
638			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v * w),
639			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 * w),
640			(Number::Float(v), Number::Int(w)) => Number::Float(v * *w as f64),
641			(v, w) => Number::from(v.to_decimal() * w.to_decimal()),
642		}
643	}
644}
645
646impl ops::Div for Number {
647	type Output = Self;
648	fn div(self, other: Self) -> Self {
649		match (self, other) {
650			(Number::Int(v), Number::Int(w)) => Number::Int(v / w),
651			(Number::Float(v), Number::Float(w)) => Number::Float(v / w),
652			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v / w),
653			(Number::Int(v), Number::Float(w)) => Number::Float(v as f64 / w),
654			(Number::Float(v), Number::Int(w)) => Number::Float(v / w as f64),
655			(v, w) => Number::from(v.as_decimal() / w.as_decimal()),
656		}
657	}
658}
659
660impl<'a, 'b> ops::Div<&'b Number> for &'a Number {
661	type Output = Number;
662	fn div(self, other: &'b Number) -> Number {
663		match (self, other) {
664			(Number::Int(v), Number::Int(w)) => Number::Int(v / w),
665			(Number::Float(v), Number::Float(w)) => Number::Float(v / w),
666			(Number::Decimal(v), Number::Decimal(w)) => Number::Decimal(v / w),
667			(Number::Int(v), Number::Float(w)) => Number::Float(*v as f64 / w),
668			(Number::Float(v), Number::Int(w)) => Number::Float(v / *w as f64),
669			(v, w) => Number::from(v.to_decimal() / w.to_decimal()),
670		}
671	}
672}
673
674impl Neg for Number {
675	type Output = Self;
676
677	fn neg(self) -> Self::Output {
678		match self {
679			Self::Int(n) => Number::Int(-n),
680			Self::Float(n) => Number::Float(-n),
681			Self::Decimal(n) => Number::Decimal(-n),
682		}
683	}
684}
685
686// ------------------------------
687
688impl Sum<Self> for Number {
689	fn sum<I>(iter: I) -> Number
690	where
691		I: Iterator<Item = Self>,
692	{
693		iter.fold(Number::Int(0), |a, b| a + b)
694	}
695}
696
697impl<'a> Sum<&'a Self> for Number {
698	fn sum<I>(iter: I) -> Number
699	where
700		I: Iterator<Item = &'a Self>,
701	{
702		iter.fold(Number::Int(0), |a, b| &a + b)
703	}
704}
705
706impl Product<Self> for Number {
707	fn product<I>(iter: I) -> Number
708	where
709		I: Iterator<Item = Self>,
710	{
711		iter.fold(Number::Int(1), |a, b| a * b)
712	}
713}
714
715impl<'a> Product<&'a Self> for Number {
716	fn product<I>(iter: I) -> Number
717	where
718		I: Iterator<Item = &'a Self>,
719	{
720		iter.fold(Number::Int(1), |a, b| &a * b)
721	}
722}
723
724pub struct Sorted<T>(pub T);
725
726pub trait Sort {
727	fn sorted(&mut self) -> Sorted<&Self>
728	where
729		Self: Sized;
730}
731
732impl Sort for Vec<Number> {
733	fn sorted(&mut self) -> Sorted<&Vec<Number>> {
734		self.sort();
735		Sorted(self)
736	}
737}