1use crate::{Stack, Value, VmError};
2
3pub trait Args {
5 fn into_stack(self, stack: &mut crate::Stack) -> Result<(), crate::VmError>;
7
8 fn into_vec(self) -> Result<Vec<crate::Value>, crate::VmError>;
10
11 fn count(&self) -> usize;
13}
14
15macro_rules! impl_into_args {
16 () => {
17 impl_into_args!{@impl 0,}
18 };
19
20 ({$ty:ident, $value:ident, $count:expr}, $({$l_ty:ident, $l_value:ident, $l_count:expr},)*) => {
21 impl_into_args!{@impl $count, {$ty, $value, $count}, $({$l_ty, $l_value, $l_count},)*}
22 impl_into_args!{$({$l_ty, $l_value, $l_count},)*}
23 };
24
25 (@impl $count:expr, $({$ty:ident, $value:ident, $ignore_count:expr},)*) => {
26 impl<$($ty,)*> Args for ($($ty,)*)
27 where
28 $($ty: $crate::ToValue,)*
29 {
30 #[allow(unused)]
31 fn into_stack(self, stack: &mut $crate::Stack) -> Result<(), $crate::VmError> {
32 let ($($value,)*) = self;
33 $(stack.push($value.to_value()?);)*
34 Ok(())
35 }
36
37 #[allow(unused)]
38 fn into_vec(self) -> Result<Vec<$crate::Value>, $crate::VmError> {
39 let ($($value,)*) = self;
40 $(let $value = <$ty>::to_value($value)?;)*
41 Ok(vec![$($value,)*])
42 }
43
44 fn count(&self) -> usize {
45 $count
46 }
47 }
48 };
49}
50
51repeat_macro!(impl_into_args);
52
53impl Args for Vec<Value> {
54 fn into_stack(self, stack: &mut Stack) -> Result<(), VmError> {
55 for value in self {
56 stack.push(value);
57 }
58 Ok(())
59 }
60
61 fn into_vec(self) -> Result<Vec<Value>, VmError> {
62 Ok(self)
63 }
64
65 fn count(&self) -> usize {
66 self.len()
67 }
68}