1use std::sync::Arc;
4
5use crate::{
6 Error,
7 Object,
8 Runtime,
9 RustObject,
10 Variable,
11};
12
13pub fn to_rust_object<T: 'static>(a: T) -> RustObject {
15 use crate::Mutex;
16 Arc::new(Mutex::new(a))
17}
18
19pub 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
27pub trait PopVariable: Sized {
29 fn pop_var(rt: &Runtime, var: &Variable) -> Result<Self, String>;
32}
33
34pub trait PushVariable {
36 fn push_var(&self) -> Variable;
38}
39
40pub trait ConvertVec4: Sized {
42 fn from(val: [f32; 4]) -> Self;
44 fn to(&self) -> [f32; 4];
46}
47
48pub trait ConvertMat4: Sized {
50 fn from(val: [[f32; 4]; 4]) -> Self;
52 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}