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