dyon/
embed.rs

1//! Traits for Dyon interop.
2
3use std::sync::Arc;
4
5use crate::{
6    Error,
7    Object,
8    Runtime,
9    RustObject,
10    Variable,
11};
12
13/// Gets value of object field.
14pub 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
21/// Implemented by types that can be popped from the runtime stack.
22pub trait PopVariable: Sized {
23    /// Converts variable to self.
24    /// The variable should be resolved before call.
25    fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String>;
26}
27
28/// Implemented by types that can be pushed to the runtime stack.
29pub trait PushVariable {
30    /// Converts from self to variable.
31    fn push_var(&self) -> Variable;
32}
33
34/// Implemented by types that can be converted to and from vec4.
35pub trait ConvertVec4: Sized {
36    /// Converts vec4 to self.
37    fn from(val: [f32; 4]) -> Self;
38    /// Converts from self to mat4.
39    fn to(&self) -> [f32; 4];
40}
41
42/// Convert from and to mat4.
43pub trait ConvertMat4: Sized {
44    /// Converts mat4 to self.
45    fn from(val: [[f32; 4]; 4]) -> Self;
46    /// Converts from self to mat4.
47    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}