Skip to main content

floria_plugin_sdk/data/math/number/
math.rs

1use super::{
2    super::{super::super::*, cast::*, operations::*},
3    number::*,
4};
5
6use {
7    duplicate::*,
8    std::{mem::*, ops::*},
9};
10
11impl Number {
12    /// True if 1.
13    pub fn is_one(self) -> bool {
14        match self {
15            Self::Integer(integer) => integer == 1,
16            Self::UnsignedInteger(unsigned_integer) => unsigned_integer == 1,
17            Self::Float(float) => float == 1.,
18        }
19    }
20
21    #[duplicate_item(
22      symbol op    op_i64    op_u64;
23      ["+"]  [add] [add_i64] [add_u64];
24      ["-"]  [sub] [sub_i64] [sub_u64];
25      ["*"]  [mul] [mul_i64] [mul_u64];
26      ["/"]  [div] [div_i64] [div_u64];
27    )]
28    /// Math operation.
29    ///
30    /// If same is true will return an error if the types are not the same.
31    pub fn op(self, right: Self, same: bool) -> Result<Self, DispatchError> {
32        if same && (discriminant(&self) != discriminant(&right)) {
33            return Err(same_type(self, right, symbol));
34        }
35
36        Ok(match (self, right) {
37            (Self::Integer(left), Self::Integer(right)) => op_i64(left, right)?.into(),
38            (Self::Integer(left), Self::UnsignedInteger(right)) => op_i64(left, into_i64(right)?)?.into(),
39            (Self::Integer(left), Self::Float(right)) => into_f64(left)?.op(right).into(),
40            (Self::UnsignedInteger(left), Self::UnsignedInteger(right)) => op_u64(left, right)?.into(),
41            (Self::UnsignedInteger(left), Self::Integer(right)) => op_i64(into_i64(left)?, into_i64(right)?)?.into(),
42            (Self::UnsignedInteger(left), Self::Float(right)) => into_f64(left)?.op(right).into(),
43            (Self::Float(left), Self::Float(right)) => left.op(right).into(),
44            (Self::Float(left), Self::Integer(right)) => left.op(into_f64(right)?).into(),
45            (Self::Float(left), Self::UnsignedInteger(right)) => left.op(into_f64(right)?).into(),
46        })
47    }
48}
49
50fn same_type(left: Number, right: Number, delimiter: &str) -> DispatchError {
51    format!("arguments not the same type: |error|{}| {} |error|{}|", left.type_name(), delimiter, right.type_name())
52}