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}