1use std::sync::Arc;
4
5use crate::{
6 Error,
7 Object,
8 Runtime,
9 RustObject,
10 Variable,
11};
12
13pub fn obj_field<T: PopVariable>(rt: &Runtime, obj: &Object, name: &str) -> Result<T, String> {
15 let var = obj
16 .get(&Arc::new(name.into()))
17 .ok_or_else(|| format!("Object has no key `{}`", name))?;
18 PopVariable::pop_var(rt, var)
19}
20
21pub trait PopVariable: Sized {
23 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String>;
26}
27
28pub trait PushVariable {
30 fn push_var(&self) -> Variable;
32}
33
34pub trait ConvertVec4: Sized {
36 fn from(val: [f32; 4]) -> Self;
38 fn to(&self) -> [f32; 4];
40}
41
42pub trait ConvertMat4: Sized {
44 fn from(val: [[f32; 4]; 4]) -> Self;
46 fn to(&self) -> [[f32; 4]; 4];
48}
49
50impl PopVariable for Variable {
51 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
52 Ok(var.deep_clone(&rt.stack))
53 }
54}
55
56impl PopVariable for RustObject {
57 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
58 if let Variable::RustObject(ref robj) = *var {
59 Ok(robj.clone())
60 } else {
61 Err(rt.expected(var, "rust_object"))
62 }
63 }
64}
65
66impl PopVariable for bool {
67 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
68 if let Variable::Bool(b, _) = *var {
69 Ok(b)
70 } else {
71 Err(rt.expected(var, "bool"))
72 }
73 }
74}
75
76impl PopVariable for String {
77 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
78 if let Variable::Str(ref s) = *var {
79 Ok((&**s).clone())
80 } else {
81 Err(rt.expected(var, "string"))
82 }
83 }
84}
85
86impl PopVariable for Arc<String> {
87 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
88 if let Variable::Str(ref s) = *var {
89 Ok(s.clone())
90 } else {
91 Err(rt.expected(var, "string"))
92 }
93 }
94}
95
96impl PopVariable for u32 {
97 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
98 if let Variable::F64(n, _) = *var {
99 Ok(n as u32)
100 } else {
101 Err(rt.expected(var, "number"))
102 }
103 }
104}
105
106impl PopVariable for usize {
107 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
108 if let Variable::F64(n, _) = *var {
109 Ok(n as usize)
110 } else {
111 Err(rt.expected(var, "number"))
112 }
113 }
114}
115
116impl PopVariable for f32 {
117 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
118 if let Variable::F64(n, _) = *var {
119 Ok(n as f32)
120 } else {
121 Err(rt.expected(var, "number"))
122 }
123 }
124}
125
126impl PopVariable for f64 {
127 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
128 if let Variable::F64(n, _) = *var {
129 Ok(n)
130 } else {
131 Err(rt.expected(var, "number"))
132 }
133 }
134}
135
136impl<T: PopVariable> PopVariable for Option<T> {
137 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
138 if let Variable::Option(ref s) = *var {
139 Ok(match *s {
140 Some(ref s) => Some(PopVariable::pop_var(rt, rt.resolve(s))?),
141 None => None,
142 })
143 } else {
144 Err(rt.expected(var, "option"))
145 }
146 }
147}
148
149impl<T: PopVariable, U: PopVariable> PopVariable for Result<T, U> {
150 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
151 if let Variable::Result(ref s) = *var {
152 Ok(match *s {
153 Ok(ref s) => Ok(PopVariable::pop_var(rt, rt.resolve(s))?),
154 Err(ref err) => Err(PopVariable::pop_var(rt, rt.resolve(&err.message))?),
155 })
156 } else {
157 Err(rt.expected(var, "result"))
158 }
159 }
160}
161
162impl<T: PopVariable> PopVariable for [T; 2] {
163 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
164 if let Variable::Array(ref arr) = *var {
165 Ok([
166 PopVariable::pop_var(rt, rt.resolve(&arr[0]))?,
167 PopVariable::pop_var(rt, rt.resolve(&arr[1]))?,
168 ])
169 } else {
170 Err(rt.expected(var, "[_; 2]"))
171 }
172 }
173}
174
175impl<T: PopVariable> PopVariable for [T; 3] {
176 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
177 if let Variable::Array(ref arr) = *var {
178 Ok([
179 PopVariable::pop_var(rt, rt.resolve(&arr[0]))?,
180 PopVariable::pop_var(rt, rt.resolve(&arr[1]))?,
181 PopVariable::pop_var(rt, rt.resolve(&arr[2]))?,
182 ])
183 } else {
184 Err(rt.expected(var, "[_; 3]"))
185 }
186 }
187}
188
189impl<T: PopVariable> PopVariable for [T; 4] {
190 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
191 if let Variable::Array(ref arr) = *var {
192 Ok([
193 PopVariable::pop_var(rt, rt.resolve(&arr[0]))?,
194 PopVariable::pop_var(rt, rt.resolve(&arr[1]))?,
195 PopVariable::pop_var(rt, rt.resolve(&arr[2]))?,
196 PopVariable::pop_var(rt, rt.resolve(&arr[3]))?,
197 ])
198 } else {
199 Err(rt.expected(var, "[_; 4]"))
200 }
201 }
202}
203
204impl<T: PopVariable, U: PopVariable> PopVariable for (T, U) {
205 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
206 if let Variable::Array(ref arr) = *var {
207 Ok((
208 PopVariable::pop_var(rt, rt.resolve(&arr[0]))?,
209 PopVariable::pop_var(rt, rt.resolve(&arr[1]))?,
210 ))
211 } else {
212 Err(rt.expected(var, "[_; 2]"))
213 }
214 }
215}
216
217impl<T: PopVariable, U: PopVariable, V: PopVariable> PopVariable for (T, U, V) {
218 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
219 if let Variable::Array(ref arr) = *var {
220 Ok((
221 PopVariable::pop_var(rt, rt.resolve(&arr[0]))?,
222 PopVariable::pop_var(rt, rt.resolve(&arr[1]))?,
223 PopVariable::pop_var(rt, rt.resolve(&arr[2]))?,
224 ))
225 } else {
226 Err(rt.expected(var, "[_; 3]"))
227 }
228 }
229}
230
231impl<T: PopVariable, U: PopVariable, V: PopVariable, W: PopVariable> PopVariable for (T, U, V, W) {
232 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
233 if let Variable::Array(ref arr) = *var {
234 Ok((
235 PopVariable::pop_var(rt, rt.resolve(&arr[0]))?,
236 PopVariable::pop_var(rt, rt.resolve(&arr[1]))?,
237 PopVariable::pop_var(rt, rt.resolve(&arr[2]))?,
238 PopVariable::pop_var(rt, rt.resolve(&arr[3]))?,
239 ))
240 } else {
241 Err(rt.expected(var, "[_; 4]"))
242 }
243 }
244}
245
246impl<T: PopVariable> PopVariable for Vec<T> {
247 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String> {
248 if let Variable::Array(ref arr) = *var {
249 let mut res = Vec::with_capacity(arr.len());
250 for it in &**arr {
251 res.push(PopVariable::pop_var(rt, rt.resolve(it))?)
252 }
253 Ok(res)
254 } else {
255 Err(rt.expected(var, "array"))
256 }
257 }
258}
259
260impl PushVariable for Variable {
261 fn push_var(&self) -> Variable {
262 self.clone()
263 }
264}
265
266impl PushVariable for RustObject {
267 fn push_var(&self) -> Variable {
268 Variable::RustObject(self.clone())
269 }
270}
271
272impl PushVariable for bool {
273 fn push_var(&self) -> Variable {
274 Variable::bool(*self)
275 }
276}
277
278impl PushVariable for u32 {
279 fn push_var(&self) -> Variable {
280 Variable::f64(f64::from(*self))
281 }
282}
283
284impl PushVariable for usize {
285 fn push_var(&self) -> Variable {
286 Variable::f64(*self as f64)
287 }
288}
289
290impl PushVariable for f32 {
291 fn push_var(&self) -> Variable {
292 Variable::f64(f64::from(*self))
293 }
294}
295
296impl PushVariable for f64 {
297 fn push_var(&self) -> Variable {
298 Variable::f64(*self)
299 }
300}
301
302impl PushVariable for str {
303 fn push_var(&self) -> Variable {
304 Variable::Str(Arc::new(self.into()))
305 }
306}
307
308impl PushVariable for String {
309 fn push_var(&self) -> Variable {
310 Variable::Str(Arc::new(self.clone()))
311 }
312}
313
314impl PushVariable for Arc<String> {
315 fn push_var(&self) -> Variable {
316 Variable::Str(self.clone())
317 }
318}
319
320impl<T: PushVariable> PushVariable for Option<T> {
321 fn push_var(&self) -> Variable {
322 Variable::Option(self.as_ref().map(|v| Box::new(v.push_var())))
323 }
324}
325
326impl<T: PushVariable, U: PushVariable> PushVariable for Result<T, U> {
327 fn push_var(&self) -> Variable {
328 Variable::Result(self.as_ref().map(|v| Box::new(v.push_var())).map_err(|e| {
329 Box::new(Error {
330 message: e.push_var(),
331 trace: vec![],
332 })
333 }))
334 }
335}
336
337impl<T: PushVariable> PushVariable for [T; 2] {
338 fn push_var(&self) -> Variable {
339 Variable::Array(Arc::new(vec![self[0].push_var(), self[1].push_var()]))
340 }
341}
342
343impl<T: PushVariable> PushVariable for [T; 3] {
344 fn push_var(&self) -> Variable {
345 Variable::Array(Arc::new(vec![
346 self[0].push_var(),
347 self[1].push_var(),
348 self[2].push_var(),
349 ]))
350 }
351}
352
353impl<T: PushVariable> PushVariable for [T; 4] {
354 fn push_var(&self) -> Variable {
355 Variable::Array(Arc::new(vec![
356 self[0].push_var(),
357 self[1].push_var(),
358 self[2].push_var(),
359 self[3].push_var(),
360 ]))
361 }
362}
363
364impl<T: PushVariable, U: PushVariable> PushVariable for (T, U) {
365 fn push_var(&self) -> Variable {
366 Variable::Array(Arc::new(vec![self.0.push_var(), self.1.push_var()]))
367 }
368}
369
370impl<T: PushVariable, U: PushVariable, V: PushVariable> PushVariable for (T, U, V) {
371 fn push_var(&self) -> Variable {
372 Variable::Array(Arc::new(vec![
373 self.0.push_var(),
374 self.1.push_var(),
375 self.2.push_var(),
376 ]))
377 }
378}
379
380impl<T: PushVariable, U: PushVariable, V: PushVariable, W: PushVariable> PushVariable
381 for (T, U, V, W)
382{
383 fn push_var(&self) -> Variable {
384 Variable::Array(Arc::new(vec![
385 self.0.push_var(),
386 self.1.push_var(),
387 self.2.push_var(),
388 self.3.push_var(),
389 ]))
390 }
391}
392
393impl<T: PushVariable> PushVariable for Vec<T> {
394 fn push_var(&self) -> Variable {
395 Variable::Array(Arc::new(self.iter().map(|it| it.push_var()).collect()))
396 }
397}
398
399impl ConvertVec4 for [f32; 2] {
400 fn from(val: [f32; 4]) -> Self {
401 [val[0], val[1]]
402 }
403 fn to(&self) -> [f32; 4] {
404 [self[0], self[1], 0.0, 0.0]
405 }
406}
407
408impl ConvertVec4 for [f32; 3] {
409 fn from(val: [f32; 4]) -> Self {
410 [val[0], val[1], val[2]]
411 }
412 fn to(&self) -> [f32; 4] {
413 [self[0], self[1], self[2], 0.0]
414 }
415}
416
417impl ConvertVec4 for [f32; 4] {
418 fn from(val: [f32; 4]) -> Self {
419 val
420 }
421 fn to(&self) -> [f32; 4] {
422 *self
423 }
424}
425
426impl ConvertVec4 for [f64; 2] {
427 fn from(val: [f32; 4]) -> Self {
428 [f64::from(val[0]), f64::from(val[1])]
429 }
430 fn to(&self) -> [f32; 4] {
431 [self[0] as f32, self[1] as f32, 0.0, 0.0]
432 }
433}
434
435impl ConvertVec4 for [f64; 3] {
436 fn from(val: [f32; 4]) -> Self {
437 [f64::from(val[0]), f64::from(val[1]), f64::from(val[2])]
438 }
439 fn to(&self) -> [f32; 4] {
440 [self[0] as f32, self[1] as f32, self[2] as f32, 0.0]
441 }
442}
443
444impl ConvertVec4 for [f64; 4] {
445 fn from(val: [f32; 4]) -> Self {
446 [
447 f64::from(val[0]),
448 f64::from(val[1]),
449 f64::from(val[2]),
450 f64::from(val[3]),
451 ]
452 }
453 fn to(&self) -> [f32; 4] {
454 [
455 self[0] as f32,
456 self[1] as f32,
457 self[2] as f32,
458 self[3] as f32,
459 ]
460 }
461}
462
463impl ConvertMat4 for [[f32; 4]; 4] {
464 fn from(val: [[f32; 4]; 4]) -> Self {
465 val
466 }
467 fn to(&self) -> [[f32; 4]; 4] {
468 *self
469 }
470}