Skip to main content

dynamic/
ops.rs

1use super::Dynamic;
2
3use std::ops::{Neg, Not};
4impl Neg for Dynamic {
5    type Output = Self;
6    fn neg(self) -> Self::Output {
7        use Dynamic::*;
8        match self {
9            I8(i) => I8(-i),
10            I16(i) => I16(-i),
11            I32(i) => I32(-i),
12            I64(i) => I64(-i),
13            F32(f) => F32(-f),
14            F64(f) => F64(-f),
15            _ => Null,
16        }
17    }
18}
19
20impl Not for Dynamic {
21    type Output = Self;
22    fn not(self) -> Self::Output {
23        match self {
24            Self::Bool(b) => Self::Bool(!b),
25            _ => Self::Null,
26        }
27    }
28}
29
30use std::ops::{Add, Div, Mul, Rem, Sub};
31
32impl Add for Dynamic {
33    type Output = Self;
34    fn add(self, rhs: Self) -> Self::Output {
35        if self.is_list() {
36            self.clone().append(rhs);
37            return self;
38        } else if rhs.is_list() {
39            rhs.clone().append(self);
40            return rhs;
41        }
42        if self.is_str() || rhs.is_str() {
43            return Self::String(format!("{}{}", self.to_string(), rhs.to_string()).into());
44        } else if self.is_f64() || rhs.is_f64() {
45            return Dynamic::F64(self.as_float().unwrap_or(0.0) + rhs.as_float().unwrap_or(0.0));
46        } else if self.is_f32() || rhs.is_f32() {
47            return Dynamic::F32(self.as_float().unwrap_or(0.0) as f32 + rhs.as_float().unwrap_or(0.0) as f32);
48        }
49        if self.is_str() || rhs.is_str() {
50            return Self::String(format!("{}{}", self.to_string(), rhs.to_string()).into());
51        }
52        if self.is_int() || rhs.is_int() {
53            return Self::I64(self.as_int().unwrap() + rhs.as_int().unwrap());
54        }
55        if self.is_uint() || rhs.is_uint() {
56            return Self::U64(self.as_uint().unwrap() + rhs.as_uint().unwrap());
57        }
58        if self.is_map() && rhs.is_map() {
59            self.append(rhs);
60        }
61        self
62    }
63}
64
65impl Mul for Dynamic {
66    type Output = Self;
67    fn mul(self, rhs: Self) -> Self::Output {
68        if self.is_f64() || rhs.is_f64() {
69            return Dynamic::F64(self.as_float().unwrap_or(0.0) * rhs.as_float().unwrap_or(0.0));
70        } else if self.is_f32() || rhs.is_f32() {
71            return Dynamic::F32(self.as_float().unwrap_or(0.0) as f32 * rhs.as_float().unwrap_or(0.0) as f32);
72        }
73        if self.is_int() || rhs.is_int() {
74            return Self::I64(self.as_int().unwrap_or(0) * rhs.as_int().unwrap_or(0));
75        }
76        if self.is_uint() || rhs.is_uint() {
77            return Self::U64(self.as_uint().unwrap_or(0) * rhs.as_uint().unwrap_or(0));
78        }
79        self
80    }
81}
82
83impl Sub for Dynamic {
84    type Output = Self;
85    fn sub(self, rhs: Self) -> Self::Output {
86        if self.is_f64() || rhs.is_f64() {
87            return Dynamic::F64(self.as_float().unwrap() - rhs.as_float().unwrap());
88        } else if self.is_f32() || rhs.is_f32() {
89            return Dynamic::F32(self.as_float().unwrap() as f32 - rhs.as_float().unwrap() as f32);
90        }
91        if self.is_int() || rhs.is_int() || self.is_uint() || rhs.is_uint() {
92            return Self::I64(self.as_int().unwrap() - rhs.as_int().unwrap());
93        }
94        if self.is_list() && rhs.is_list() {
95            if self.len() == rhs.len() {}
96        }
97        self
98    }
99}
100
101impl Div for Dynamic {
102    type Output = Self;
103    fn div(self, rhs: Self) -> Self::Output {
104        if self.is_f64() || rhs.is_f64() {
105            return Dynamic::F64(self.as_float().unwrap() / rhs.as_float().unwrap());
106        } else if self.is_f32() || rhs.is_f32() {
107            return Dynamic::F32(self.as_float().unwrap() as f32 / rhs.as_float().unwrap() as f32);
108        }
109        if self.is_int() || rhs.is_int() || self.is_uint() || rhs.is_uint() {
110            return Self::I64(self.as_int().unwrap() / rhs.as_int().unwrap());
111        }
112        self
113    }
114}
115
116impl Rem for Dynamic {
117    type Output = Self;
118    fn rem(self, rhs: Self) -> Self::Output {
119        if self.is_int() || rhs.is_int() || self.is_uint() || rhs.is_uint() {
120            return Self::I64(self.as_int().unwrap() % rhs.as_int().unwrap());
121        }
122        self
123    }
124}
125
126use std::ops::{Shl, Shr};
127
128impl Shl for Dynamic {
129    type Output = Self;
130    fn shl(self, rhs: Self) -> Self::Output {
131        use Dynamic::*;
132        let shift = u64::try_from(rhs).unwrap();
133        match self {
134            I8(i) => I8(i << shift),
135            I16(i) => I16(i << shift),
136            I32(i) => I32(i << shift),
137            I64(i) => I64(i << shift),
138            U8(i) => U8(i << shift),
139            U16(i) => U16(i << shift),
140            U32(i) => U32(i << shift),
141            U64(i) => U64(i << shift),
142            _ => panic!("Cannot shift non-integer types"),
143        }
144    }
145}
146
147impl Shr for Dynamic {
148    type Output = Self;
149    fn shr(self, rhs: Self) -> Self::Output {
150        use Dynamic::*;
151        let shift = u64::try_from(rhs).unwrap();
152        match self {
153            I8(i) => I8(i >> shift),
154            I16(i) => I16(i >> shift),
155            I32(i) => I32(i >> shift),
156            I64(i) => I64(i >> shift),
157            U8(i) => U8(i >> shift),
158            U16(i) => U16(i >> shift),
159            U32(i) => U32(i >> shift),
160            U64(i) => U64(i >> shift),
161            _ => panic!("Cannot shift non-integer types"),
162        }
163    }
164}
165
166use std::ops::{BitAnd, BitOr, BitXor};
167impl BitAnd for Dynamic {
168    type Output = Self;
169    fn bitand(self, rhs: Self) -> Self::Output {
170        let ty = self.get_type() + rhs.get_type();
171        let left = ty.force(self).unwrap();
172        let right = ty.force(rhs).unwrap();
173        match (left, right) {
174            (Dynamic::I8(l), Dynamic::I8(r)) => Dynamic::I8(l & r),
175            (Dynamic::I16(l), Dynamic::I16(r)) => Dynamic::I16(l & r),
176            (Dynamic::I32(l), Dynamic::I32(r)) => Dynamic::I32(l & r),
177            (Dynamic::I64(l), Dynamic::I64(r)) => Dynamic::I64(l & r),
178            (Dynamic::U8(l), Dynamic::U8(r)) => Dynamic::U8(l & r),
179            (Dynamic::U16(l), Dynamic::U16(r)) => Dynamic::U16(l & r),
180            (Dynamic::U32(l), Dynamic::U32(r)) => Dynamic::U32(l & r),
181            (Dynamic::U64(l), Dynamic::U64(r)) => Dynamic::U64(l & r),
182            (_, _) => Dynamic::Null,
183        }
184    }
185}
186
187impl BitOr for Dynamic {
188    type Output = Self;
189    fn bitor(self, rhs: Self) -> Self::Output {
190        let ty = self.get_type() + rhs.get_type();
191        let left = ty.force(self).unwrap();
192        let right = ty.force(rhs).unwrap();
193        match (left, right) {
194            (Dynamic::I8(l), Dynamic::I8(r)) => Dynamic::I8(l | r),
195            (Dynamic::I16(l), Dynamic::I16(r)) => Dynamic::I16(l | r),
196            (Dynamic::I32(l), Dynamic::I32(r)) => Dynamic::I32(l | r),
197            (Dynamic::I64(l), Dynamic::I64(r)) => Dynamic::I64(l | r),
198            (Dynamic::U8(l), Dynamic::U8(r)) => Dynamic::U8(l | r),
199            (Dynamic::U16(l), Dynamic::U16(r)) => Dynamic::U16(l | r),
200            (Dynamic::U32(l), Dynamic::U32(r)) => Dynamic::U32(l | r),
201            (Dynamic::U64(l), Dynamic::U64(r)) => Dynamic::U64(l | r),
202            (_, _) => Dynamic::Null,
203        }
204    }
205}
206
207impl BitXor for Dynamic {
208    type Output = Self;
209    fn bitxor(self, rhs: Self) -> Self::Output {
210        let ty = self.get_type() + rhs.get_type();
211        let left = ty.force(self).unwrap();
212        let right = ty.force(rhs).unwrap();
213        match (left, right) {
214            (Dynamic::I8(l), Dynamic::I8(r)) => Dynamic::I8(l ^ r),
215            (Dynamic::I16(l), Dynamic::I16(r)) => Dynamic::I16(l ^ r),
216            (Dynamic::I32(l), Dynamic::I32(r)) => Dynamic::I32(l ^ r),
217            (Dynamic::I64(l), Dynamic::I64(r)) => Dynamic::I64(l ^ r),
218            (Dynamic::U8(l), Dynamic::U8(r)) => Dynamic::U8(l ^ r),
219            (Dynamic::U16(l), Dynamic::U16(r)) => Dynamic::U16(l ^ r),
220            (Dynamic::U32(l), Dynamic::U32(r)) => Dynamic::U32(l ^ r),
221            (Dynamic::U64(l), Dynamic::U64(r)) => Dynamic::U64(l ^ r),
222            (_, _) => Dynamic::Null,
223        }
224    }
225}